目录
- Matplotlib绘图
- 基础
- 图形的组成
- 图形的层次
- Matplotlib的三个层次
- 底层-后台层(Backends Layer)
- 特点
- 中间层-艺术家层(Artist Layer)
- 特点
- 上层-脚本层(Scripting Layer)
- 特点
- 小结-1
- 绘制基本的图表
- 绘制散点图scatter
- 绘制条形图bar与直方图hist
- 绘制饼图pie
- 绘制箱线图boxplot
- 绘制折线图plot
- 绘制核密度图plot
- 小结-2
- 添加文字
- 参数
- 调整坐标轴
- 绘制子图
- 小结-3
- 面向对象(Object oriented)的API接口
- 代码分析
- 面向对象
- 比较pylot模块提供的函数与Axes对象自带的函数
- 常见Matplotlib类
- 高级用法
- 误差条图形
- 置信区间的计算
- 热力图(heatmap)
Matplotlib绘图
基础
图形的组成
图形的最外面是文字部分,包括标题,x轴标签,y轴标签。其次是主刻度标签和副刻度标签(不太常用),然后是坐标轴,最里面是数据。
- 数据的表现形式多种多样,这个例子中有散点和折线。
- 如果存在多种图形样式可以添加图例。
- 图例尽量不要遮挡住数据,一般会放在角落。
- 根据数据的特点,还会添加背景网格帮助我们比较数据的变化或大小。
图形的层次
在人工绘画时我们都需要一张纸,在Matplotlib中,这张纸叫画布(图中蓝色框,英文为 Canvas)。
其次需要绘图框(图中绿色框,英文为 Figure),绘图框是允许绘图的最大空间,也是最高的图形容器。
在绘图框里我们才可以画画。这里的画就是 “图”。我们把这个“图”叫子图(图4中黄色框,英文为Axes或Subplot)。子图的范围就是黄色框中包含的所有图形元素。
Axes和Subplot语义相同,但是Axes用的较广泛些。
Matplotlib的三个层次
Matplotlib包括三个层次:后台层、艺术家层和脚本层。它们在逻辑上是堆叠的关系。
底层-后台层(Backends Layer)
后台层是Matplotlib的底层结构,用来提供整个绘图的核心引擎。
例如:后端负责在不同操作系统,用户界面,显示器中配置绘图文件,并让图像都能正确显示。
特点
- 处理用户对图形的交互,例如鼠标点击或者键盘输入等
- 后台层是整个Matplotlib的核心,用来提供画布,渲染图形,在屏幕上展示\
- Matplotlib里面,我们不经常接触到后台层
- 有几个基础类(Base Classes)
-
FigureCanvas
类:提供画布 -
Renderer
类:绘制并渲染图形 -
Event
类:处理用户交互,例如鼠标点击等
每个基础类下面还有子类(Subclasses),它们都是为了提供绘图所需的基本功能与环境。
中间层-艺术家层(Artist Layer)
艺术家层顾名思义,就像艺术家一样在画板上作画,它控制着图形的线条、形状、轴、文字等样式。
它是整个结构中的中间层,负责对象的生成与管理。它知道每条线段有多长,点的形状是什么。如果说后台层是绘图工具,艺术家层可看作是作画的画家。
特点
- 创建图形中的各种绘图元素,例如点、线、坐标轴、文字等,并将它们按顺序排列好
- 有一个基础类(Base Class):
Artist
类,包含每一个“艺术家”应该具备的共同属性,例如坐标轴的画法等
-
Artist
类下也有很多子类。例如有绘制坐标轴的,处理文字的等。 - 这些子类可以分成两类
- 图元类(Primitives)
- 图形中出现的各个元素
- 例如线段、圆等。这里的子类有
Line2D
、Rectangle
、Circle
、Text
等。
- 容器类(Containers)
- 归纳和整理这些图形元素
- 容器类最大的子类就是绘图框(
Figure
),还有XAxis
、YAxis
、Axes
、Subplot
等。
上层-脚本层(Scripting Layer)
这一层实际上是一个“翻译官”,将我们所写的代码告诉给“艺术家”,这样艺术家才知道我们需要画什么。
在Matplotlib中我们使用的这位翻译官名字叫做
pyplot
直接和“艺术家”进行交流,称之为面向对象画图。
正是由于在脚本层和艺术家层均可作图,因此Matplotlib的语法对于初学者来说比较混乱。
特点
- 负责协调后台层和艺术家层,让我们能用简单的编程语言与其他两层交流。
小结-1
Matplotlib的绘图逻辑要比以上复杂得多,在Matplotlib里面,还有很多支持性组件,包括配置支持组件和实用程序模块组件等。
详细可以参考《Mastering Matplotlib》 一书。
绘制基本的图表
直接调用Matplotlib的脚本层翻译官
pyplot
完成基本绘图任务。
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
#plt为pyplot的缩写,这个别名已在国际上约定俗成
- Matplotlib在绘图时所接受的数据类型包括列表list和Numpy的多维数组(ndarray)。
- Matplotlib的官方文档中说数据框(Pandas DataFrame)数据不能保证每次都能正确运行,建议转化成矩阵(matrix)。
绘制散点图scatter
散点图用来描绘两个数值型特征的关系,它的对象最好是两个连续型特征,如果有一个是离散型也可以。
- 绘制散点图所使用的函数是
plt.scatter()
- 在
Matplotlib
中,绘图最后都需使用plt.show()
函数,将图形输出。
plt.scatter(x, y)
plt.show()
绘制条形图bar与直方图hist
条形图用来看类别型数据的分布
直方图用来看连续型数据的分布。
- 条形图函数
plt.bar()
不会自动统计个数,故可能需要手动提取表格中的数据的取值集合以及每一个取值下的计数 - 绘制条形图的函数是
bar()
,包含两个必要参数:x
和y
(也就是高度)。 - 使用
width
参数来调整每个矩形的宽度
plt.bar(x, height = y, width = 0.2)
plt.show()
- 直方图使用
plt.hist()
函数来绘制。 width
参数代表一个矩形应该覆盖x轴上的范围多少。
-
width
和条形图的width
参数意义不同。
plt.hist(x, width = 1)
plt.show()
绘制饼图pie
饼图可以很好的看出各个部分占总数的百分比。饼图的对象是一个离散型或类别型数据。
- 绘制饼图我们使用
plt.pie()
函数。! - 这个函数只有一个必要参数,那就是
x
- 可选参数很多,例如:
- 标记(
y
) - 显示百分比的参数
autopct
。
plt.pie(x, labels=y, autopct='%0.0f%%')#autopct='%0.0f%%'显示百分比
plt.show()
绘制箱线图boxplot
箱线图用来观察连续特征的分布状况,通过箱线图,除了能够判断数据的离散程度,还可以直观地识别数据中的离群值。
- 绘制箱线图的函数是
plt.boxplot()
- 最简单的箱线图只包含一个连续型特征,例如价格(price)
- 复杂一点的箱线图包括多个连续型特征。
- 多个array放在一个列表里面就可以直接调用
plt.boxplot()
函数画图。
- 可选参数
-
labels
可用来更改x轴坐标。[list] - 设置
positions
来调整这两个箱线图的位置。[list] -
showfliers
参数可以设置是否显示离群值。[boolean] -
vert
参数可用来调整箱线图方向。[boolean]
plt.boxplot(x, labels=['x1'])
plt.show()
绘制折线图plot
折线图能很好的看出数据的变化或趋势。
- 折线图也需要两个参数,一个是x轴(离散或类别型),一个是y轴(数值型)。
- 绘制折线图的函数为
plt.plot()
- 折线图中的点的前后顺序是很重要的。
- 排序可以与zip搭配,使数据一一对应:
combined = list(zip(x,y))
- 使用
combined.sort()
排序 - 使用
uncombined = list(zip(*combined))
拆开列表
- 最常用的可选参数就是调整线段的样式,叫
linestyle
- plot的样式fmt参数为str类型
- fmt只是快速设置基本样式的缩写。
- 例如:
"ro-"
表示:红色,实心大圆点,实线
绘制核密度图plot
核密度图需要的是连续型随机变量。核密度图又是核密度估计,核密度估计的“估计”代表估计一个随机变量的值。
- 绘制核密度图仍然使用
plt.plot()
函数。 - 在核密度图中,我们通过拟合函数的方法使原始数据中的线段被拆得非常短,从而得到一条平滑的曲线。
- Matplotlib在绘制核密度图上不占优势,更好的替代品为Seaborn包,或者R软件。
小结-2
函数名 | 必要参数 | 绘图效果 | 可选参数1 | 可选参数2 | 可选参数3 | 官方链接 |
plt.scatter() | x, y | 散点图 | marker调整形状 | s调整大小 | c调整颜色 | |
plt.bar() | x, height | 条形图 | width调整宽度 | alpha调整透明度 | color调整颜色 | |
plt.hist() | x | 直方图 | bins条形个数 | align条形对齐 | color调整颜色 | |
plt.pie() | x | 饼图 | labels添加成分标注 | radius更改圆形半径 | color调整颜色 | |
plt.boxplot() | x | 箱线图 | widths箱线宽度 | labels添加箱线标注 | vert更改画图方向 | |
plt.plot() | x, y | 折线图 | linestyle选择线样式 | alpha调整透明度 | color调整颜色 |
- alpha的范围是0-1,0代表完全透明,1代表完全不透明。
-
plt.violinplot()
就是绘制小提琴图(箱线图的一个变种) - 在Jupyter notebook中
- 输入
%matplotlib notebook
"魔法"命令。此时不需使用plt.show()
函数,Jupyter会自动生成交互式图像 - 输入
%matplotlib inline
"魔法"命令,此时不需使用plt.show()
函数,Jupyter会自动生成非交互式图像 - 魔法命令一旦运行后就全局生效。
添加文字
-
plt.title()
来添加标题 -
plt.xlabel()
来添加x轴标签 -
plt.ylabel()
来添加y轴标签 plt.text()
来添加自定义文字
- 添加自定义文字时,前两个参数为自定义文字第一个字符的坐标,即字符’f’的坐标为(200,0)
- 例如:
plt.text(200, 0, 'f(x)=sin(x)')
plt.legend()
来添加图例
- 添加图例时,用
labels
来添加图例的标签
参数
- 颜色的参数和之前一样为
color
- 标题和图例的位置都用
loc
表示。
- 标题的常用位置是(
left
,center
,right
) - 图例的常用位置是(
upper left
,center
,upper right
,lower left
,lower center
,lower right
)
- 透明度是
alpha
- 字体大小是
fontsize
- 轴标签与轴的距离可以用
labelpad
参数调整 - 显示特殊文字,我们需要使用
r'$xxxx$'
格式[TeX语法]
- 其中
xxxx
就是要显示的特殊文字 - 特殊文字都以
\
开始,并且希腊字母是它们的英文拼写方式。例如r'$\alpha$'
- 例如:
r'$\alpha$ (alpha)'
- 分数用
\frac{}{}
表示 - 根号用
\sqrt{}
表示 - …
调整坐标轴
- 修改最大(小)值,用
xlim()
或者ylim()
函数
- 例如:
plt.xlim(0, 100)
- 让坐标轴以log的形式显示。这时就需要使用
plt.xscale('log')
或者plt.yscale('log')
来调整。 - 添加主、副刻度网格用
grid()
函数
- major主刻度网格:
plt.grid(which='major', linewidth=2, linestyle='--')
- minor副刻度网格:
plt.grid(which='minor', linestyle=':', linewidth=0.3, color='b')
- 需要这个开启副刻度显示选项才能显示副刻度
plt.minorticks_on()
plt.grid(True)
默认参数添加网格xticks()
yticks()
来修改主刻度显示范围。
- 第一个参数是要修改的位置,第二个参数是要填写的新标签。
rotation
参数可以调整主刻度标签的方向。- 注意第一个参数接受的是
ndarray
的结构【PS:实测list也可以】 - 使用
np.array()
来创建显示范围,或使用np.arange()
来指定大小值及其间距来创建显示范围。
- 注意在使用
np.arange()
创建显示范围时,设定的最大值要稍大于需要显示的最大值,否则最后一个值将无法显示。 - 例如:
x_label = ['A','B','C']
y_label = ['first','second','third']
plt.xticks(np.array([0,60,120]), x_label, rotation='vertical')
plt.yticks(np.arange(min(y), max(y)+0.1, 0.5), y_label)
plt.tick_params()
函数可以调节主刻度标签大小,主刻度长短,坐标轴标签颜色等。
- 使用
axis
参数来指定要修改的坐标轴 color
为主刻度颜色size
为主刻度长度labelcolor
为主刻度标签颜色labelsize
为主刻度标签大小
plt.tick_params(axis = "x", color = "green", size = 30)
plt.tick_params(axis = "y", labelcolor = "red", labelsize = 15)
绘制子图
- 绘制子图的函数是
plt.subplot()
- 在
plt.subplot()
里面要说明当前子图的位置坐标。
- 例如:
plt.subplot(1,2,1)
- 代表绘制一个1行2列的子图矩阵中的第一个子图。
-
plt.subplot()
也支持省略逗号的方法。即plt.subplot(121)
- 执行完第一个
plt.subplot()
后,就开始绘制当前子图。当调整完所有细节后,再写下一个plt.subplot()
开始绘制第二个子图。
import matplotlib.pyplot as plt
import numpy as np
# 绘制第一个子图
plt.subplot(1,2,1)
plt.plot(x, y)
plt.title('Subplot 1')
plt.xlabel('X lable')
plt.ylabel('Y lable')
plt.legend(['sin(x)'])
# 绘制第二个子图
plt.subplot(1,2,2)
plt.scatter(x, y, c='r', alpha=0.1, s=1)
plt.title('Subplot 2')
plt.xlabel('X axis')
plt.ylabel('Y axis')
- 用函数
plt.tight_layout()
自动设置子图间距。 - 使用
plt.suptitle()
函数(注意拼写)来添加绘图框标题
- 该函数中也可以添加颜色(
color
),透明度(alpha
)等参数,用法和其他文本类函数的参数一样。
- 绘图框标题的位置
- 通过使用
plt.subplots_adjust()
函数调整绘图框的位置,让出绘图框标题的位置
或plt.suptitle()
中的可选参数x
和y
调整绘图框标题
参数 | 作用 |
left = 0.8 | 子图左侧的位置 |
right = 0.2 | 子图右侧的位置 |
top = 0.8 | 子图上方的位置 |
bottom = 0.2 | 子图下方的位置 |
wspace = 0.2 | 子图之间保留的宽度 |
hspace = 0.2 | 子图之间保留的高度 |
小结-3
-
plt.figure(figsize=(15, 8))
调整图片大小
函数名 | 作用 |
plt.xlabel() | 添加及修改x轴标签 |
plt.ylabel() | 添加及修改y轴标签 |
plt.text() | 添加及修改自定义文字 |
plt.xlim() | 设置x轴范围 |
plt.ylim() | 设置x轴范围 |
plt.grid() | 添加网格 |
plt.xtick() | 修改x轴主刻度标签 |
plt.ytick() | 修改y轴主刻度标签 |
plt.tick_params() | 修改主刻度颜色,长度 |
plt.legend() | 添加及修改图例 |
plt.subplot() | 绘制多张子图 |
plt.suptitle() | 添加及修改绘图框标题 |
plt.subplots_adjust() | 修改子图与绘图框间距 |
plt.tight_layout() | 自动调整子图间距 |
plt.minorticks_on() | 开启副刻度显示 |
面向对象(Object oriented)的API接口
代码分析
import matplotlib.pyplot as plt#1
import numpy as np#2
x = np.arange(0, 10, 0.5)#3
plt.plot(x, 10*x, 'r-.',
x, x**2, 'bs',
x, x**3, 'g^')#4
- 在执行第一行代码的时候,matplotlib.pyplot会选择系统默认(或者用户指定)的backend。然后,matplotlib.pyplot会执行一系列配置任务:创建一个figure manager的工厂函数(factory function);选择合适的绘图函数(draw function)等
- 在执行第四行代码的时候,
- matplotlib.pyplot会获取(没有则创建)一个figure manager对象,并获取对应的figure canvas对象
- 从figure canvas中,得到Figure对象
- 从Figure中,获取当前Axes对象
- Axes对象调用
plot()
函数,清除已经存在的Axes对象,然后根据提供的数据进行绘图
3.在执行第五行代码的时候,Matplotlib获取当前活跃的figure manager对象,对象调用canvas.draw()
函数,显示图形
位于脚本层的pyplot模块提供的方便快捷的绘图函数实质上是在创建一系列类的对象(Figure, Axes等),并由这些对象来去调用相应函数,具体执行绘图的操作。
pyplot模块位于面向对象的编程接口上方,为用户隐藏了Matplotlib的运行细节。
面向对象
对象实例 | 说明 |
FigureCanvas | Figure对象的容器 |
Figure | 多个Axes对象实例的容器 |
Axes | 包含图形基本元素(如文本,直线,曲线等)的矩形区域 |
Matplotlib在获取figure canvas对象之后,将Figure对象实例保存在FigureCanvas中,然后可以向Figure实例添加多个Axes对象实例,完成图形的"搭建"。
#面向对象的matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import numpy as np
from matplotlib.font_manager import FontProperties
%matplotlib inline
x = np.arange(0, 10, 0.5)
fig = Figure()
FigureCanvas(fig)
axes = fig.add_subplot(111)
custom_font = FontProperties(fname = '/楷体_GB2312.ttf')#设置中文字体
axes.set_title('面向对象的编程风格', fontproperties =custom_font, fontsize = 15)
axes.plot(x, 10*x, 'r-.')
axes.plot(x, x**2, 'bs')
axes.plot(x, x**3, 'g^')
fig
- 由于我们直接创建Figure类的对象实例,代码将不会产生figure manager对象,因此无法直接使用
show()/draw()
等函数,展示图形。因此,我们需要使用Ipython的display()
函数来显示绘制完成的图形。[Warning]:目前不知道如何调用display()显示图片
比较pylot模块提供的函数与Axes对象自带的函数
pyplot模块:plt | Axes对象:axes |
plt.plot() | axes.plot() |
plt.scatter() | axes.scatter() |
plt.pie() | axes.pie() |
plt.hist() | axes.hist() |
plt.grid() | axes.grid() |
plt.legend() | axes.legend() |
plt.title() | axes.set_title() |
plt.xlabel() plt.ylabel() | axes.set_xlabel() axes.set_ylabel() |
- 很相似,实质上,
pyplot
模块的函数也就是对Axes
对象相应函数的再次封装。
常见Matplotlib类
图形元素 | 元素所属的类 | (base class) |
线条 | matplotlib.line.line2D | - |
轴,刻度 | matplotlib.axis.tick | matplotlib.artist.Artist |
轴标签,标题等 | matplotlib.text.Text | matplotlib.artist.Artist |
Axes对象 | matplotlib.axes._axes.Axes | matplotlib.artist.Artist |
Figure对象 | matplotlib.figure.Figure | - |
- 通常我们混合使用
- 在pyplot的代码中,我们可以通过调用指定的函数,返回当前图形的Figure对象或者AxesSubPlot对象。
函数 | 返回对象 |
plt.gcf() | Figure对象 |
plt.gca() figure.gca() | AxesSubPlot对象 |
- 通过
plt.gcf()
获得当前图形的Figure对象
- 通过pyplot的
figure()
函数返回Figure对象
- 调用Figure对象fig的
gca()
函数,返回当前的AxesSubplot对象。
#一个例子
fig, axes_list = plt.subplots(2,1)
axes_list[0].plot(x1, y1, 'bo')
axes_list[1].plot(x2, y2, 'r--')
添加图形元素 | 使用的函数 |
图形的标题 | set_title() |
X轴标签 | set_xlabel() |
Y轴标签 | set_ylabel() |
X轴刻度 | set_xticks() |
Y轴刻度 | set_yticks() |
X轴刻度特征名称 | set_xsticklabels() |
Y轴刻度特征名称 | set_ysticklabels() |
高级用法
误差条图形
误差条图形用来反映数据的离散程度,可以显示数据各个特征的均值和误差。
一般和其他图形结合使用
- 误差条图形使用函数
plt.errorbar(x, y, yerr=None, xerr=None, fmt='',...)
- 部分参数
-
x
,y
[数据位置] xerr=None
,yerr=None
[x, y轴误差线大小]
- 标量或数组类型shape(N,) or shape(2,N)
- 一维数组时,误差线大小为每个数据点对称的±值
- 如[1, 2, 3, …]
- 二维数组时,每个数据点分别使用-和+值。
- 第一行包含较低的错误,第二行包含较高的错误。
- 如[[1,2], [4,5], …]
fmt
[误差线样式]
- 使用“none”(不区分大小写)来绘制没有任何格式的误差线
- …
- 范围(range)
- 描述性 数据样本的取值区间
- 标准差(standard deviation, sd)
- 描述性 数据样本距离均值的平均差异
- 标准误差(standard error, se)
- 推断性 多次抽样下,样本均值的变化
- 置信区间(95%)(confidence interval)
- 推断性 95%的概率下均值会出现的范围
- 样本总体必须是正态的,置信区间才有效。
置信区间的计算
- 计算样本平均值
- 计算样本标准差(std)σ(参数ddof【Delta Degrees of Freedom,Delta自由度】此处默认值为1)
- 计算样本标准误差(标准误,sem)
- 置信度系数zα/2
- 例如:置信度95%,即α=0.95,那么α/2=0.475,通过查表得知zα/2=1.96
- 计算置信区间
热力图(heatmap)
热力图(heatmap)是一种以颜色高亮的程度来表征数据集变量数值大小的直观图形,可以让用户快读了解掌握数据集各个变量的取值信息。
- 使用函数
plt.colorbar()
import matplotlib.pyplot as plt
import numpy as np
data = [[1,2,3,4],[2,3,4,5],[3,4,5,6]]#二维数据
fig, ax = plt.subplots()#添加一个子图
heatmap = ax.pcolormesh(data, cmap = plt.cm.Blues, alpha = 0.8)
fig.colorbar(heatmap)
#设置轴刻度
ax.set_xticks(np.arange(4) + 0.5, minor=False)#+0.5使刻度显示在图像中心
ax.set_yticks(np.arange(3) + 0.5, minor=False)
#设置轴刻度标签
ax.set_xticklabels([1,2,3,4], minor = False,rotation = 90)
ax.set_yticklabels(['A','B','C'], minor = False)
plt.show()