Matplotlib 中文手册:Pyplot 教程
Matplotlib
Pyplot 教程
对 pyplot 接口的相关说明。
Pyplot 简介
matplotlib.pyplot
是使 Matplotlib 像 MATLAB 一样工作的命令样式函数的集合。每个 pyplot
函数都会对图形进行一些更改。比如说创建图形,在图形中创建绘图区域,在绘图区域中绘制一些线,用标签装饰您所绘制的图像等。
在 matplotlib.pyplot
中,函数的调用会保留各种状态,以便跟踪当前图形和绘图区域内的图像挂件,并将绘图函数定向到当前轴。这里值得一提的是,这个轴指的是图形的轴部分,就是我们在第一章节中不断地讲到的轴,而不是数学意义上的轴。
注意:
pyplot API 通常不如 OO API 来的灵活轻巧。您在此处所看到的绝大多数的函数调用也可以称作是 Axes 对象中的方法调用。我们建议浏览相关教程和示例以了解其工作原理。
使用 pyplot 来做数据可视化的速度非常快,比如说:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
![eb691669c3819fa6b0a9ba12dd42c26b.png](https://i-blog.csdnimg.cn/blog_migrate/7d8f6881d2652425382e00ca3827fdc7.png)
您可能很好奇为什么 X 轴的范围是 ,而且 Y 轴的范围是 。这是因为如果您向 plot()
函数提供单个列表或者数组,则 matplotlib 会自动假定它是 Y 轴的序列,并自动为您产生 X 值。由于 Python 的范围从 0 开始,因此默认的 X 向量的长度会与 Y 轴相同,但从 X 是从 0 开始的。因此 X 轴的数据就是 。
plot()
是一种通用命令,它能够接受任意数量的参数。比如说,您想要绘制 X 与 Y 的关系,那么可以用以下代码来进行操作:
plt.plot([1,2,3,4],[1,4,9,16])
![f7d94eba185f63d22eefc862558feaae.png](https://i-blog.csdnimg.cn/blog_migrate/29fca11f649257a0081484bba0ebad3b.png)
所生成图形的 X 轴就会从 1 开始,而不是最初的默认值 0 。
自定义您的绘图样式
对于每一个 参数对,都有一个可选的第三参数,它是表示图的颜色和线条类型的格式字符串。格式字符串的字母和符号都来自 MATLAB,您得将颜色字符串和线条字符串连接在一起。一开始的默认符号串是 ‘b-’,这是一条蓝色实线。假如说你想用红色圆圈来绘制以上内容,你可以使用下面的代码:
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')
plt.axis([0, 6, 0, 20])
plt.show()
![3bc82c6a56aadb1f3f5446fb2d61278a.png](https://i-blog.csdnimg.cn/blog_migrate/69ce157491761ad56fb118abcf316693.png)
有关线型和格式字符串的完整API,请参见 plot()
文档。上例中的 axis()
命令采用 [xmin, xmax, ymin, ymax]
的参数列形式。
如果 matplotlib 仅限于使用列表,那对于数值处理来说是毫无用处的。一般来说,您会经常使用numpy数组。实际上,所有序列都在程序内部转换为 numpy 数组。下面的示例说明了在一个命令中使用数组绘制多行具有不同格式样式的线条情况。
import matplotlib.pyplot as plt
import numpy as np
# evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)
# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
![d9c837e9e6c165b316e98b285b5f350e.png](https://i-blog.csdnimg.cn/blog_migrate/9e545d719b39a318c50147ddf0708096.png)
绘图中的关键字符串
在某些情况下,您会拥有一些带特定格式的数据,这种数据允许您使用字符串来访问特定的变量。比如说,numpy.recarray
或者 pandas.DataFrame
。
Matplotlib 给予您 data
关键字以方便您为此类对象提供参数。如果您提供了的话,您就可以使用与这些变量相对应的字符串来生成您的图形,例如:
import matplotlib.pyplot as plt
import numpy as np
data = {'a': np.arange(50),
'c': np.random.randint(0, 50, 50),
'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
plt.scatter('a', 'b', c='c', s='d', data=data)
plt.xlabel('entry a')
plt.ylabel('entry b')
plt.show()
![23ccc06b668e903ec8e7c5356f0da16d.png](https://i-blog.csdnimg.cn/blog_migrate/48280b2fcb2d6ab9ffc92eb5db24c532.png)
使用分类变量绘制图像
当然,您也可以使用分类变量来绘制您的图像。Matplotlib 允许您将分类变量直接传递给许多绘图函数,比如说:
import matplotlib.pyplot as plt
import numpy as np
names = ['group_a', 'group_b', 'group_c']
values = [1, 10, 100]
plt.figure(figsize=(9, 3))
plt.subplot(131)
plt.bar(names, values)
plt.subplot(132)
plt.scatter(names, values)
plt.subplot(133)
plt.plot(names, values)
plt.suptitle('Categorical Plotting')
plt.show()
![96c7dfe43d6c9ee028c4f4df2bcffdff.png](https://i-blog.csdnimg.cn/blog_migrate/f02abe7059954ce81696c9fd7bb92c4d.png)
线属性的设置
线具有很多很多可以设置的属性,比如说线宽啊,破折号样式啊,抗锯齿啊等等,这里大概地提一下几种设置线属性的方法,具体的相关 API 可以参见 matplotlib.lines.Line2D
。
使用关键字
plt.plot(x, y, linewidth=2.0)
#官方原版英文教程中只给了上面这一句,我自己又亲自打了一个,如下所示:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], linewidth=5.0) #参数序列依次对应的是 x, y, linewidth
plt.axis([0, 6, 0, 20])
plt.show()
![cd9889746895b1b2e154c9dcd993a489.png](https://i-blog.csdnimg.cn/blog_migrate/b662ebbfd506a15a05e97f7bb8ce8907.png)
使用
Line2D
的设置方法,例如
line, = plt.plot(x, y, '-')
line.set_antialiased(False) # 关闭抗锯齿
使用
setp()
命令。下面的示例使用 MATLAB 样式的命令在行列表上设置多个属性。setp
很明显地对对象列表或者单个对象进行了相关工作。您也可以使用 Pyhton 关键字参数或 MATLAB 样式的(str,val)
对进行相关操作:
lines = plt.plot(x1, y1, x2, y2)
# 使用关键字
plt.setp(lines, color='r', linewidth=2.0)
# 或者使用 MATLAB 风格的串值对
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
当然还有其他的相关参数案例,请移步到 API 。
复合图像
MATLAB 和 pyplot
都具有当前图形和当前轴的概念。所有的绘图命令均适用于当前轴。gca()
函数返回当前轴(一个matplotlib.axes.Axes
实例);而 gcf()
则返回当前图形(一个 matplotlib.figure.Figure
实例)。但是您并不用为折腾这个是哪个而烦恼,因为所有操作都是在幕后的,您只需要考虑您的逻辑即可。下面是创建两个子图的相关代码:
import matplotlib.pyplot as plt
import numpy as np
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure()
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()
![4e90bc2cfd5f8324bff0ba6f434193ef.png](https://i-blog.csdnimg.cn/blog_migrate/855bafbbfb8ec1c349b9450a925333a7.png)
这个 figure()
命令是可以选择的,在默认情况下将会创建一个 figure(1)
,就好比如果没有用户手动指定任意轴,就会默认创建一个 subplot(111)
。subplot()
命令指定了其内参数为 numrows, numcols, plot_number
,其中 plot_number
的范围是 。如果 ,则 subplot()
命令中的逗号分隔是可选的,也就是说 subplot(211)
和 subplot(2,1,1)
是等价的。
您可以创建具有任意数量的子图和轴。如果要手动放置轴的话,也就是没有自动对齐到矩形网格上,可以使用 axes()
命令,这个命令能够将所有的值以分数形式表示的位置指定为 axes([left, bottom, width, height])
。有关于手动放置轴的相关示例,可以参见 Axes Demo;如果是跟大量子图有关的,可以参见 基本子图 Demo 。
当然,您可以通过多次调用 figure()
来创建多个图形,这些图形都带有递增的图形编号。与此同时,这些图形都可以包含多个轴与多个子图,如下所示:
import matplotlib.pyplot as plt
plt.figure(1) # 第一张图形
plt.subplot(211) # 第一张图形的第一个子图
plt.plot([1, 2, 3])
plt.subplot(212) # 第二个子图
plt.plot([4, 5, 6])
plt.figure(2) # 第二张图形
plt.plot([4, 5, 6])
plt.figure(1)
plt.subplot(211)
plt.title('Easy as 1, 2, 3')
plt.show()
![4f0be6e89e1196dcc561d537e41ba30f.png](https://i-blog.csdnimg.cn/blog_migrate/80529ac1343557ba6d5df3a982866216.png)
最后,你可以使用 clf()
来清除当前图形;使用 cla()
来清除当前轴。
值得一提的是,如果你需要制作大量的图形,推荐使用 close()
来显示关闭图形,否则这些图形并不会因为你把它的窗口关闭了就杀掉了进程,它会一直保存在 pyploy 的内部引用中,直到调用 close()
为止。
文字处理
text()
命令能够在任意位置添加文本,而 xlabel(),ylabel(),title()
则是在指定位置添加文本。例如:
import matplotlib.pyplot as plt
import numpy as np
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()
![00c4c53f6e92bc36d95487795d91c8cc.png](https://i-blog.csdnimg.cn/blog_migrate/dc0d969f507f1e5fb0a172b38f8bf631.png)
所有的 text()
命令都会返回一个 matplotlib.text.Text
实例。当然,你也可以使用 setp()
或者关键字参数来自定义属性。
t = plt.xlabel('my data', fontsize=14, color='red')
你可以在相关 API 中得到更详尽地说明。
在文本中使用数学表达式
Matplotlib 支持在任何文本中插入 TeX 方程,使用一对美元符号括起来的 TeX 表达式,例如:
plt.title(r'$\sigma_i=15$')
标题字符串前的 r
很重要。它表示该字符串是原始字符串,并且不将反斜杠视为 Python 转义。matplotlib 具有内置的 TeX 表达式解析器和布局引擎,并附带了自己的数学字体。其他的详细信息,请参见具体的 API 。因此在这里,您可以跨平台使用数学文本,而无需安装 TeX 。
文本注释
上面我们提到的只是基础的 text()
命令,这个命令能够将文本放置在轴上的任意位置。而文本其实是常常用来对某些功能进行注释的,annotate()
命令提供了一个注释的办法。在这里需要注意的是,参数 xy
表示的是所要注释的位置和文本xytext
的位置。这两个参数都是 (x,y)
元组。
ax = plt.subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)
plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)
plt.ylim(-2, 2)
plt.show()
![881863ab49a86c62c250f479a4550e47.png](https://i-blog.csdnimg.cn/blog_migrate/e6855b731f6b7a9d4a56fb667c179add.png)
关于注释的其他问题,请参见具体的 API。
对数轴与其他非线性轴
matplotlib.pyplot
不仅仅支持线性数轴,还支持其他非线性数轴。更改数轴的方法很简单,下面就展示了四个图的相关示例,这四个图的 Y 轴数据相同但是比例不同。
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import NullFormatter
np.random.seed(19680801)
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))
plt.figure()
# 线
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)
# 对数
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)
# 对称对数
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthreshy=0.01)
plt.title('symlog')
plt.grid(True)
# 离散
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
plt.gca().yaxis.set_minor_formatter(NullFormatter())
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
wspace=0.35)
plt.show()
![26f3b91a555ba46cd09e132d996b952b.png](https://i-blog.csdnimg.cn/blog_migrate/cd669c2695a02bc645981af613972193.png)
当然你也可以自主添加比例尺,详情请查看有关 API 。
+