Matplotlib 可以说是最常用的 Python 绘图模块,其实现了许多类似 Matlab 中的函数,可以帮助用户轻松获得高质量的图形。
Pyplot
matplotlib.pyplot 提供了一系列与 Matlab 绘图命令对应的函数,如果你熟悉 Matlab 绘图将很容易上手。
1 | # 使用 Jupyter notebook 时在开头添加如下命令使图形嵌入当前页面 |
绘制简单折线:1
2
3
4
5
6
7
8
9
10import matplotlib.pyplot as plt
plt.figure() # 创建一个新的图
plt.plot([1, 2, 3, 4], [1, 4, 9, 16]) # 传入一些 x 和 y 的值来绘制折线
plt.title('Line Chart: Polyline') # 设置标题
plt.xlabel('x') # 设置 x 轴标签文字
plt.ylabel('y') # 设置 y 轴标签文字
plt.show() # 显示图形
plot()
不仅支持 list,还可使用 numpy 数组(实际上其内部会将所有的输入序列转换为 numpy 数组):1
2
3
4
5
6import numpy as np
x = np.linspace(-5, 5, 128)
y = x ** 2
plt.plot(x, y, 'r')
plt.show()
前面的例子通过第三个参数指定了线的颜色,而没有使用 Matplotlib 的默认配置。很多情况下,Matplotlib 的默认配置就够用了,但如果你想进行自定义,你可以调整大多数的默认配置,包括图片大小、线宽、颜色、样式、坐标轴、网格、文字与字体属性等。设置的方式在本节后面的内容中详细介绍。
plot()
可以输入任意多的参数,因而支持在同一个命令中绘制多条不同的线:1
2
3x = np.arange(0, 5, 0.2)
plt.plot(x, x, 'r', x, x**2, 'g', x, x**3, 'b')
plt.show()
设置线的属性
设置线的属性有多种方式:
- 使用
plot()
时通过关键参数进行设置 - 使用
plot()
时通过样式字符串进行设置 - 通过
Line2D
对象的方法进行设置 - 使用
setp()
批量设置
使用关键参数
可以通过指定关键参数来设定线的相关属性,对应的其实就是 Line2D 的属性。
1 | import matplotlib.pyplot as plt |
以下链接是颜色、线样式、Marker样式的相关参考:
使用样式字符串
样式字符串支持用简洁的代码进行基本属性的设置,样式字符串的形式如下:1
fmt = '[color][marker][line]'
示例:1
2
3
4
5
6
7
8
9import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2*np.pi, 2*np.pi, 96)
y = np.sin(x)
# 使用样式字符串,设置颜色为绿色,设置Marker样式为点
plt.plot(x, y, "g.")
plt.show()
常用的颜色
字符 | 颜色 |
---|---|
‘b’ | blue |
‘g’ | green |
‘r’ | red |
‘c’ | cyan |
‘m’ | magenta |
‘y’ | yellow |
‘k’ | black |
‘w’ | white |
常用的线样式
字符 | 样式 |
---|---|
‘-‘ | 实线 |
‘—‘ | 虚线 |
‘-.’ | 点划线 |
‘:’ | 点线 |
常用的Marker
字符 | 样式 |
---|---|
‘.’ | point marker |
‘,’ | pixel marker |
‘o’ | circle marker |
‘v’ | triangle_down marker |
‘^’ | triangle_up marker |
‘<’ | triangle_left marker |
‘>’ | triangle_right marker |
‘1’ | tri_down marker |
‘2’ | tri_up marker |
‘3’ | tri_left marker |
‘4’ | tri_right marker |
‘s’ | square marker |
‘p’ | pentagon marker |
‘*’ | star marker |
‘h’ | hexagon1 marker |
‘H’ | hexagon2 marker |
‘+’ | plus marker |
‘x’ | x marker |
‘D’ | diamond marker |
‘d’ | thin_diamond marker |
使用 Line2D 对象
1 | import matplotlib.pyplot as plt |
更多线的属性设置请参考 matplotlib.lines.Line2D
批量设置
1 | import matplotlib.pyplot as plt |
设置图形属性
设置图形的大小、分辨率:
1 | import matplotlib.pyplot as plt |
更多图形属性设置请参考 matplotlib.figure.Figure
添加图例
下面的例子在左下角添加图例,图例的文字在调用plot()
时由 label 参数值指定:
1 | import matplotlib.pyplot as plt |
更多图例的细节请参考 matplotlib.pyplot.legend
添加文字
我们可使用text()
在指定位置添加文字,xlabel()
, ylabel()
和title()
可以指定坐标轴和标题的文字。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2*np.pi, 2*np.pi, 96)
plt.figure(figsize=(8,3), dpi=100)
plt.plot(x, np.sin(x), color="blue", linewidth=2.0, linestyle="-", label="sin")
plt.plot(x, np.cos(x), color="red", linewidth=2.0, linestyle="--", label="cos")
plt.legend(loc='lower left', frameon=False)
# 添加文字标注
plt.xlabel("x")
plt.ylabel("y")
plt.title('Line Chart')
plt.show()
更多使用文字的示例请参考官方指南-文本
使用数学表达式
另外,Matplotlib 支持 LaTeX,可以很方便地在两个 $ 符号之间用 LaTeX 表示数学公式。修改前面的例子如下:1
2
3
4
5
6
7
8
9
10plt.figure(figsize=(8,3), dpi=100)
plt.plot(x, np.sin(x), color="blue", linewidth=2.0, linestyle="-", label=r"$sin(\theta)$")
plt.plot(x, np.cos(x), color="red", linewidth=2.0, linestyle="--", label=r"$cos(\theta)$")
plt.legend(loc='lower left', frameon=False)
# 使用数学表达式
plt.xlabel(r"$\theta$")
plt.text(2.2, 0.9, r"$sin(\frac{\pi}{2})=1$")
plt.show()
更多使用 Latex 的示例请参考 官方指南-Latex
添加注记
在前面的例子基础上加入下面的代码:1
2
3
4
5# 添加注记
plt.annotate(r"$sin(\frac{\pi}{2})=-1$", xy=(-np.pi/2, -1), xytext=(-2.3, -0.5),
arrowprops=dict(facecolor='black', shrink=0.0))
plt.show()
更多使用注记的示例请参考官方指南-注记
设置坐标轴
使用xlim()
和ylim()
可以控制坐标轴的范围。xticks()
和yticks()
可以控制坐标轴上的标记。通过pyplot.gca()
可以获得 Axes 对象,设置Axes
的属性可以进行更多的控制。
坐标轴范围、坐标轴标记
设置坐标轴范围以及标记:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2*np.pi, 2*np.pi, 96)
plt.figure(figsize=(8,3), dpi=100)
plt.plot(x, np.sin(x), color="blue", linewidth=2.0, linestyle="-", label=r"$sin(\theta)$")
plt.plot(x, np.cos(x), color="red", linewidth=2.0, linestyle="--", label=r"$cos(\theta)$")
plt.legend(loc='lower left', frameon=False)
# 指定坐标轴范围
plt.xlim([-2*np.pi*1.1, 2*np.pi*1.1])
plt.ylim([-1*1.2, 1*1.2])
# 另一种指定坐标轴范围的方式
#plt.axis([-2*np.pi*1.1, 2*np.pi*1.1, -1*1.2, 1*1.2])
# 设置坐标轴标记
xlabels = [r'$-2\pi$', r'$-3\pi/2$', r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$', r'$+3\pi/2$', r'$+2\pi$']
plt.xticks(np.linspace(-2*np.pi, 2*np.pi, 9), xlabels)
plt.yticks([-1, 0, +1], [r'$-1$', r'$0$', r'$+1$'])
plt.show()
移动坐标轴
添加下面的代码调整坐标轴的位置:1
2
3
4
5
6
7
8
9
10
11
12
13
14xlabels = [r'$-2\pi$', r'$-3\pi/2$', r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$', r'$+3\pi/2$', r'$+2\pi$']
plt.xticks(np.linspace(-2*np.pi, 2*np.pi, 9), xlabels)
plt.yticks([-1, +1], [r'$-1$', r'$+1$'])
# 移动坐标轴
ax = plt.gca()
ax.spines['right'].set_color('none') # 隐藏右侧的轴线
ax.spines['top'].set_color('none') # 隐藏顶部的轴线
ax.xaxis.set_ticks_position('bottom') # 指定底部轴线显示标记
ax.spines['bottom'].set_position(('data',0)) # 设置底部轴线的位置(横轴)
ax.yaxis.set_ticks_position('left') # 指定左侧轴线显示标记
ax.spines['left'].set_position(('data',0)) # 设置左侧轴线的位置(纵轴)
plt.show()
子图
有多种方式绘制一个拥有多个子图的图形:
- 使用 pyplot 的
subplots()
命令 - 使用 pyplot 的
subplot2grid()
命令 - 使用 gridspec 模块
- 使用 Figure 对象的
add_axes()
方法
subplots
绘制一个含有两个子图的图形:1
2
3
4
5
6
7
8
9
10
11
12
13import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2*np.pi, 2*np.pi, 96)
plt.figure(figsize=(8,3), dpi=100)
plt.subplot(2, 1, 1)
plt.plot(x, np.sin(x), "b-")
plt.subplot(2, 1, 2)
plt.plot(x, np.cos(x), "r--")
plt.show()
两行两列四个子图:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22x1 = np.linspace(-2*np.pi, 0, 96)
x2 = np.linspace(0, 2*np.pi, 96)
plt.figure(figsize=(8,4), dpi=100)
plt.subplot(2, 2, 1)
plt.plot(x1, np.sin(x1), "b-")
plt.xticks(np.linspace(-2*np.pi, 0, 5), [r'$-2\pi$', r'$-3\pi/2$', r'$-\pi$', r'$-\pi/2$', r'$0$'])
plt.subplot(2, 2, 2)
plt.plot(x2, np.sin(x2), "b-")
plt.xticks(np.linspace(0, 2*np.pi, 5), [r'$0$', r'$\pi/2$', r'$\pi$', r'$3\pi/2$', r'$2\pi$'])
plt.subplot(2, 2, 3)
plt.plot(x1, np.cos(x1), "r--")
plt.xticks(np.linspace(-2*np.pi, 0, 5), [r'$-2\pi$', r'$-3\pi/2$', r'$-\pi$', r'$-\pi/2$', r'$0$'])
plt.subplot(2, 2, 4)
plt.plot(x2, np.cos(x2), "r--")
plt.xticks(np.linspace(0, 2*np.pi, 5), [r'$0$', r'$\pi/2$', r'$\pi$', r'$3\pi/2$', r'$2\pi$'])
plt.show()
其他绘制子图的方式请参考官方指南-布局
其他图形
更多的图形请参考 https://matplotlib.org/gallery.html
动画
可以使用下面两种 Animation 类来实现动画:
- FuncAnimation - 通过反复调用指定的函数func来制作动画
- ArtistAnimation - 通过一个固定的
Artist
对象集合来实现动画
生成的动画可使用Animation.save
或Animation.to_html5_video
保存(可能需要安装 ffmpeg)。
动画的具体使用请参考 https://matplotlib.org/api/animation_api.html
参考资料
https://matplotlib.org/users/beginner.html
https://matplotlib.org/users/tutorials.html
https://matplotlib.org/gallery.html
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html