数据可视化-Matplotlib绘制可视化图表

数据可视化

Matplotlib绘制可视化图表

一、实验名称

Matplotlib绘制可视化图表

二、实验目的

通过该实验的实践,要求学生能够熟练使用Matplotlib基本图表的可视化展示,掌握使用这工具绘制图表的一般化流程,掌握使用Matplot实现特征分析,掌握使用Matplotlib实现数据分布情况分析,以及基于Matplotlib的复杂场景应用等。

三、实验原理

Matplotlib 是 Python 的可视化基础库,作图风格和 MATLAB 类似,所以称为 Matplotlib

python中的很多可视化库都基于Matplotlib进行了封装,如Seaborn 是一个基于 Matplotlib 的高级可视化效果库,针对 Matplotlib 做了更高级的封装,让作图变得更加容易。你可以用短小的代码绘制更多维度数据的可视化效果图。

使用matplotlib可以展示可视化的多种基本图表

四、实验步骤

1、打开终端Terminal,准备执行安装命令行

2、环境准备

2.1 打开jupyter

在打开的浏览器中,新建python3文件

3、基础图表

柱形图

柱形图通常用于直观的对比数据,在实际工作中使用频率很高,在Matplotlib中可以通过bar()即可绘制出柱形图。

import matplotlib.pyplot as plt
plt.bar([1, 2, 3, 4], [1, 4, 2, 3])  # 绘制图像
plt.show()

如果想修改柱子的颜色,宽度,可以通过color和width参数进行修改;

color:支持通过代码快速配置常见的颜色,如r代表红色,blue代表蓝色,也支持十六进制和RGB(A)格式颜色配置;

width:数值范围0-1,默认0.8;

import matplotlib.pyplot as plt
plt.bar([1, 2, 3, 4], [1, 4, 2, 3], color=(0.2, 1.0, 1.0), width=0.5)  # 绘制图像
plt.show()
条形图

条形图同样常用来进行数据的对比展示,可以简单看作是柱形图经过翻转90度后的图表,使用barh()可以进行条形图的绘制;

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.barh(["深圳", "广州", "北京", "上海"], [1, 4, 2, 3])  # 绘制图像
plt.show()

需要注意,当柱子翻转过来之后,修改柱子的“宽度”在条形图从参数width变成了height;

import matplotlib.pyplot as plt
plt.barh(["深圳", "广州", "北京", "上海"], [1, 4, 2, 3], height=0.5, color="#0aff00")  # 绘制图像
plt.show()
折线图

折线图通常用于展示一段时间内的趋势,可以通过plot进行折线图的绘制;

import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [1, 4, 2, 3])  # 绘制图像
plt.show()

通过linewidth和linestyle可以进行线宽和线型的配置;

linestyle可接受的参数如下:

至于展示出来是什么样式,大家可以依次去尝试一下

import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [1, 4, 2, 3], color='blue', linewidth=2, linestyle='-.')  # 绘制图像
plt.show()

通过marker和makersize可以绘制带标记点的折线图;

支持的maker样式如下:

输出为:

import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [1, 4, 2, 3], color='blue', linewidth=2, linestyle='-.', marker='*', markersize=15)  # 绘制图像
plt.show()

面积图

面积图其实就是折线图的另一种展示显示,相当于是对折线图进行了区域颜色填充,在matplotlib中可以通过stackplot()进行面积图的绘制;

注:其实从Matplotlib的命名来看,stackplot是堆叠折线图,不过默认是填充了颜色的,所以我们可以当作面积图来使用。

import matplotlib.pyplot as plt
plt.stackplot([1, 2, 3, 4], [1, 4, 2, 3], color=(0.4, 0.2, 0.1, 0.1))  # 绘制图像
plt.show()

饼图

饼图通常用于展示各种类别数据的占比,在matplotlib中可以通过pie()进行饼图的绘制;

import matplotlib.pyplot as plt
# labels用于饼图标签的设置
plt.pie([1, 4, 2, 3], labels=["深圳", "广州", "北京", "上海"])  # 绘制图像
plt.show()

在制作饼图的时候我们通常需要展示百分比,在Matplotlib中可以通过atuopct参数进行配置;

import matplotlib.pyplot as plt
# labels用于饼图标签的设置
plt.pie([1, 4, 2, 3], labels=["深圳", "广州", "北京", "上海"], autopct='%.2f%%')  # 绘制图像
plt.show()

我们可以通过将其中一块区域分离来进行数据的强调显示;

import matplotlib.pyplot as plt
# labels用于饼图标签的设置
plt.pie([1, 4, 2, 3], labels=["深圳", "广州", "北京", "上海"], autopct='%.2f%%', explode=[0, 0, 0.2, 0])  # 绘制图像
plt.show()

可以通过参数labeldistance和pctdistance进行标签和百分比显示的位置,1表示一个圆心到圆周的距离;

import matplotlib.pyplot as plt
# labels用于饼图标签的设置
plt.pie([1, 4, 2, 3], labels=["深圳", "广州", "北京", "上海"], autopct='%.2f%%', labeldistance=1.2, pctdistance=0.6)  # 绘制图像
plt.show()

通过对wedgeprops参数设置还可以绘制圆环图;

import matplotlib.pyplot as plt
# labels用于饼图标签的设置
plt.pie([1, 4, 2, 3], labels=["深圳", "广州", "北京", "上海"], 
        autopct='%.2f%%', pctdistance=0.8,
        wedgeprops={'width': 0.3, 'linewidth': 2, 'edgecolor': 'w'})  # 绘制图像
plt.show()

散点图

散点图通常用于展示数据之间的相关关系,可以通过scatter进行散点图的绘制;

import random
import matplotlib.pyplot as plt
data_x = [random.randint(1, 100) for _ in range(100)]
data_y = [random.randint(1, 100) for _ in range(100)]   
plt.scatter(data_x, data_y)
plt.show()

散点图除了可以通过xy轴反映数据之外,还可以通过「点」的颜色和大小来反映数据,可以最多展示4个维度的数据;

import numpy as np
import matplotlib.pyplot as plt
N = 30
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 
plt.scatter(x, y, 
            # 图形大小
            s=area, 
            # 颜色
            c=colors, 
            # 透明度
            alpha=0.2)
plt.show()

除此之外,我们还可以通过Marker去设置标记点的形状,通过edgecolor去设置标记点的边框颜色;

import numpy as np
import matplotlib.pyplot as plt
N = 30
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 
plt.scatter(x, y, 
            # 图形大小
            s=area, 
            # 颜色
            c=colors, 
            # 透明度
            alpha=0.2,
            # 标记点形状
            marker='*',
            # 边框颜色
            edgecolor='blue'
            )
plt.show()

4、图表元素配置

基础例子
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
plt.plot(x, y, linestyle='-.', marker='p', markersize=10)  # 绘制图像
plt.show()

修改画布尺寸

可以通过plt.figure来创建一张宽6英寸,长8英寸的画布;

import matplotlib.pyplot as plt
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
plt.plot(x, y, linestyle='-.', marker='o', markersize=10)  # 绘制图像
plt.show()

修改中文字体

Matplotlib中遇到中文显示方块的问题,可以通过plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'解决;

我们还可以设置的中为字体有SimSun(宋体),SimHei(黑体),Kaiti(楷体)等

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
plt.plot(x, y, linestyle='-.', marker='o', markersize=10)  # 绘制图像
plt.show()

添加图表标题

通过plt.title可以在Matplotlib设置标题,字体样式可以通过fontdict进行设置;

通过loc参数可以设置标题显示位置,支持的参数有center(居中),left(靠左),right(靠右)显示;

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
plt.title("销售趋势图", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 15}, loc='left')
plt.plot(x, y, linestyle='-.', marker='o', markersize=10)  # 绘制图像
plt.show()

添加图例

通过plt.legend可以给图表添加图例,图例通常用来说明图表中数据每个系列的数据的;

在下图中,我们添加两条折线,一条表示华东地区销售情况,一条表示华中的销售情况,需要注意的是我们在通过plt.plot()绘制折线的时候,需要通过label参数设置该系列数据的名称,后续才能通过plt.legend添加;

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y1 = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
y2 = [102, 121, 138, 154, 171, 178, 199, 231, 228, 202, 231, 271]
plt.title("销售趋势图", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 15}, loc='left')
plt.plot(x, y1, linestyle='-.', marker='o', markersize=10, color='r', label='华东')  # 绘制图像
plt.plot(x, y2, linestyle='-', marker='o', markersize=10, color='y', label='华中')  # 绘制图像
plt.xlabel("月份", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.ylabel("销售额(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.legend(loc='best', fontsize=12) # best:matplotlib根据图表自动选择最优位置
plt.show()

添加数据标签

可以通过plt.text对图表添加文本,但是一次只能添加一个点,所以如果要给每个数据项都添加标签的话,我们需要通过for循环来进行</p>

plt.text 有三个重要的参数:x、y 、s,通过x和y确定显示位置,s为需要显示的文本,另外还有va和ha两个参数设置文本的显示位置(靠左、靠右、居中等);

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y1 = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
y2 = [102, 121, 138, 154, 171, 178, 199, 231, 228, 202, 231, 271]
plt.title("销售趋势图", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 15}, loc='left')
plt.plot(x, y1, linestyle='-.', marker='o', markersize=10, color='r', label='华东')  # 绘制图像
plt.plot(x, y2, linestyle='-', marker='o', markersize=10, color='y', label='华中')  # 绘制图像
plt.xlabel("月份", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.ylabel("销售额(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.legend(loc='best', fontsize=12) # best:matplotlib根据图表自动选择最优位置
for a, b, c in zip(x, y1, y2):
    plt.text(a, b, b, va='bottom', fontdict={"size":14})
    plt.text(a, c, c, va='top', fontdict={"size":14})
plt.show()

网格线和坐标轴范围

通过可以添加网格线可以方便用户容易看出数据项的大致值,通过上述展示所有数据标签时,可能会让整个图表比较杂乱,我们可以选择使用网格线来展示数据项大致数据值;

参数b为True时展示网格线,axis支持x、y、both三个值,分别表示展示纵向网格线,横向网格线和纵向横向都展示;

其余线型配置与配置折线风格的参数类似;

可以通过plt.ylim和plt.xlim分别对y轴和x轴的坐标范围进行配置,譬如我们可以设置y轴的起点为50;

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y1 = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
y2 = [102, 121, 138, 154, 171, 178, 199, 231, 228, 202, 231, 271]
plt.title("销售趋势图", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 15}, loc='left')
plt.plot(x, y1, linestyle='-.', marker='o', markersize=10, color='r', label='华东')  # 绘制图像
plt.plot(x, y2, linestyle='-', marker='o', markersize=10, color='y', label='华中')  # 绘制图像
plt.xlabel("月份", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.ylabel("销售额(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.legend(loc='best', fontsize=12) # best:matplotlib根据图表自动选择最优位置
# 设置坐标轴范围
plt.ylim(50, 300)
# 添加网格线
plt.grid(axis='y', linestyle='--', linewidth=1, color='grey')
plt.show()

5、复杂场景

多图

有时候一个图表并不能说明问题,需要通过多子图进行展现;

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
plt.subplot(2, 2, 1)
plt.bar(x, y)
plt.subplot(2, 2, 2)
plt.pie(y, labels=x)
plt.subplot(2, 2, 3)
plt.plot(x, y)
plt.subplot(2, 2, 4)
plt.barh(x, y)
plt.show()

plt.subplot(2, 2, 1)表示将整张画布划分成2*2块区域,并置顶在第一块区域中绘制图表;

接下来通过plt.bar(x, y)在指定区域内绘制一个柱形图;

Matplotlib中有两种绘图方式,同样的效果我们可以通过如下代码来实现;

import matplotlib.pyplot as plt
x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
fig, axs = plt.subplots(2, 2)
axs[0][0].bar(x, y)
axs[0][1].pie(y, labels=x)
axs[1][0].plot(x, y)
axs[1][1].barh(x, y)
plt.show()

不均匀子图

有些情况下,我们并不希望所有的图表都是一样的大小,不然显得整个画布毫无重点;

我们可以通过.add_gridspec()将整个画布划分成不均匀的区域;

spec = fig.add_gridspec(nrows=2, ncols=2, width_ratios=[1, 3], height_ratios=[1,2]) 表示将整个画布裁剪为2行2列的区域,width_ratios=[1, 3]表示横向将两列的宽度按照1:3进行裁剪,同理height_ratios=[1,2]表示纵向按照1:2进行裁剪

import matplotlib.pyplot as plt
x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
fig = plt.figure(figsize=(10, 8))
spec = fig.add_gridspec(nrows=2, ncols=2, width_ratios=[1, 3], height_ratios=[1,2])
ax = fig.add_subplot(spec[0, 0])
ax.bar(x, y)
ax = fig.add_subplot(spec[0, 1])
ax.plot(x, y)
ax = fig.add_subplot(spec[1, 0])
ax.pie(y, labels=x)
ax = fig.add_subplot(spec[1, 1])
ax.barh(x, y)
plt.show()

spec还支持切片的方式,譬如我们将第二行展示为整个条形图;

import matplotlib.pyplot as plt
x = ["深圳", "广州", "北京", "上海"]
y = [1, 3, 2, 5]
fig = plt.figure(figsize=(10, 8))
spec = fig.add_gridspec(nrows=2, ncols=2, width_ratios=[1, 3], height_ratios=[1,2])
ax = fig.add_subplot(spec[0, 0])
ax.bar(x, y)
ax = fig.add_subplot(spec[0, 1])
ax.plot(x, y)
# 第二行整块区域显示条形图
ax = fig.add_subplot(spec[1, :])
ax.barh(x, y)
# 调整各区域之间的距离
plt.subplots_adjust(hspace=0.3, wspace=0.2)
plt.show()

双Y轴

当我们多个系列的数据值量级差别太大时,依赖同一个坐标轴来展示通常效果很差,比如需要将销售额和利润同时展示出来;

这时候我们可以通过plt.twix()添加次坐标轴;

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.figure(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y1 = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
y2 = [2, 11, 18, 14, 11, 18, 19, 21, 28, 22, 21, 21]
# 绘制柱形图
plt.title("销售趋势图", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 15}, loc='left')
plt.bar(x, y1, color='b', alpha=.5, label='销售额')  # 绘制图像
plt.ylabel("销售额(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.ylim(100, 250)
# 添加次坐标轴
plt.twinx()
plt.plot(x, y2, linestyle='-', marker='o', markersize=10, color='r', label='利润')  # 绘制图像
plt.ylabel("利润(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.show()

另外需要注意一点,twinx或者twiny方法会返回一个共享x轴或者y轴的新的axes,如果我们通过plt.subplots生成ax后,再绘制第二个折线图时,需要在这个新生成的ax1上绘图;

fig, ax = plt.subplots(figsize=(8, 6))
x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
y1 = [123, 145, 152, 182, 147, 138, 189, 201, 203, 211, 201, 182]
y2 = [2, 11, 18, 14, 11, 18, 19, 21, 28, 22, 21, 21]
# 绘制柱形图
ax.set_title("销售趋势图", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 15}, loc='left')
ax.bar(x, y1, color='b', alpha=.5, label='销售额')  # 绘制图像
ax.set_ylabel("销售额(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
ax.set_ylim(100, 250)
# 添加次坐标轴
ax1 = ax.twinx()
ax1.plot(x, y2, linestyle='-', marker='o', markersize=10, color='r', label='利润')  # 绘制图像
ax1.set_ylabel("利润(万元)", fontdict={'family':'Microsoft YaHei', 'color': 'k', 'size': 12}, labelpad=10)
plt.show()

五、实验总结

在实验中,通过实践练习,提高学生使用Matplotlib进行基本图表可视化操作的熟练度,掌握Matplotlib绘制图表的一般性的流程,养成规范绘图的习惯。

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值