> 文章列表 > Matplotlib 入门

Matplotlib 入门

Matplotlib 入门

Matplotlib 入门

matplotlib的引入约定

matplotlib的通常引入约定为:

import matplotlib.pyplot as plt 

第一幅图:在Jupyter中运行(或在IPython中运行)以下代码,就可以创建一个简单的图形。如果代码正确,会看到下图。

import matplotlib.pyplot as plt
import numpy as np
data = np.arange(10)
plt.plot(data)
plt.show()

Matplotlib 入门

Figure和Subplot

matplotlib的图像都位于Figure对象中(可以理解为一个画布)。你可以用plt.figure创建一个新的Figure(即创建一块画布):

fig = plt.figure()

plt.figure有一些选项,特别是figsize,它用于确保当图片保存到磁盘时具有一定的大小和纵横比。

不能通过空Figure绘图,必须用add_subplot创建一个或多个subplot才行:

ax1 = fig.add_subplot(2, 2, 1)

这条代码的意思是:图像应该是2×2的(即最多4张图),且当前选中的是4个subplot中的第一个 (编号从1开始)。如果再把后面两个subplot也创建出来,最终得到的图像如下图所示。这里,我们运行同一个小窗里的所有命令:

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

在这里插入图片描述

如果这时执行一条绘图命令(如plt.plot([1.5, 3.5, -2, 1.6])),matplotlib就会在最后一个用过的 subplot(如果没有则创建一个)上进行绘制,隐藏创建figure和subplot的过程。因此,如果我们执行下列命令,你就会得到下图所示的结果(图形可能不一样,但是会在第三幅子图中进行绘图):

plt.plot(np.random.randn(50).cumsum(), "k--")

Matplotlib 入门

"k–"是一个线型选项,用于告诉matplotlib绘制黑色虚线图。上面那些由fig.add_subplot所返回的对象是AxesSubplot对象,直接调用它们的实例方法就可以在其它空着的格子里面画图了,如下图所 示:

ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)  # 绘制直方图
ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))  #绘制散点图

Matplotlib 入门

你可以在matplotlib的文档中找到各种图表类型。创建包含subplot网格的figure是一个非常常见的任务,matplotlib有一个更为方便的方法 plt.subplots,它可以创建一个新的Figure,并返回一个含有已创建的subplot对象的NumPy数组:

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
axes
# 输出
array([[<AxesSubplot:>, <AxesSubplot:>],[<AxesSubplot:>, <AxesSubplot:>]], dtype=object)

Matplotlib 入门

这是非常实用的,因为可以轻松地对axes数组进行索引,就好像是一个二维数组一样,例如 axes[0,1]。你还可以通过sharexsharey指定subplot应该具有相同的X轴或Y轴。在比较相同范围的数据时,这也是非常实用的,否则,matplotlib会自动缩放各图表的界限。有关该方法的更多信息,可以参见下表。

参数 说明
nrows subplt的行数
ncols subplt的列数
sharex 所有subplot应该使用相同的X刻度(调节xlim将会影响所有subplot
sharey 所有subplot应该使用相同的Y轴刻度(调节ylim将会影响所有subplot
subplot_kw 用于创建各subplot的关键字字典
fig_kw 创建figure时的其他关键字,如plt.subplots(2,2,figsize=(8,6))

调整subplot周围的间距

默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关,因此,如果你调整了图像大小(不管是编程还是手工),间距也会自动调整。利用Figure的subplots_adjust方法可以轻而易举地修改间距,此外,它也是个顶级函数:

subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

wspacehspace用于控制宽度和高度的百分比,可以用作subplot之间的间距。下面是一个简单的例子,其中我将间距收缩到了0,如下图所示:

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
for i in range(2):for j in range(2):axes[i, j].hist(np.random.randn(500), bins=50, color="k", alpha=0.5)
plt.subplots_adjust(wspace=0, hspace=0)

Matplotlib 入门

不难看出,其中的轴标签重叠了。matplotlib不会检查标签是否重叠,所以对于这种情况,你只能自己设定刻度位置和刻度标签。

颜色、标记和线性

matplotlibplot函数接受一组XY坐标,还可以接受一个表示颜色和线型的字符串缩写。例如,要根据xy绘制绿色虚线,可以执行如下代码:

ax.plot(x, y, 'g--')

这种在一个字符串中指定颜色和线型的方式非常方便。在实际中,如果你是用代码绘图,你可能不想通过处理字符串来获得想要的格式。通过下面这种更为明确的方式也能得到同样的效果:

ax.plot(x, y, linestyle='--', color='g')

常用的颜色可以使用颜色缩写,你也可以指定颜色码(例如,‘#CECECE’)。你可以通过查看plot的 文档字符串查看所有线型的合集。

线图可以使用标记强调数据点。因为matplotlib可以创建连续线图,在点之间进行插值,因此有时可能不太容易看出真实数据点的位置。标记也可以放到格式字符串中,但标记类型和线型必须放在颜色后面,如下图所示:

from numpy.random import randn
plt.plot(randn(30).cumsum(), 'ko--')

Matplotlib 入门

还可以将其写成更为明确的形式:

plt.plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')

在线型图中,非实际数据点默认是按线性方式插值的。可以通过drawstyle选项修改,如下图所示:

data = np.random.randn(30).cumsum()
plt.plot(data, "k--", label="Default")
plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
plt.legend(loc='best')

Matplotlib 入门

这里,因为传递了label参数到 plot,我们可以创建一个plot图例,指明每条使用plt.legend的线。必须调用plt.legend(或使用ax.legend,如果引用了轴的话)来创建图例,无论你 绘图时是否传递label标签选项。

刻度、标签和图例

对于大多数的图表装饰项,其主要实现方式有两种:一是使用过程型的pyplot接口(例如matplotlib.pyplot),二是更为面向对象的原生matplotlib API。

pyplot接口的设计目的就是交互式使用,含有诸如xlimxticksxticklabels之类的方法。它们分别 控制图表的范围、刻度位置、刻度标签等。其使用方式有以下两种:

  • 调用时不带参数,则返回当前的参数值(例如,plt.xlim()返回当前的X轴绘图范围)。
  • 调用时不带参数,则返回当前的参数值(例如,plt.xlim()返回当前的X轴绘图范围)。

所有这些方法都是对当前或最近创建的AxesSubplot起作用的。它们各自对应subplot对象上的两个方法,以xlim为例,就是ax.get_xlimax.set_xlim。我更喜欢使用subplot的实例方法(因为我喜欢明确的事情,而且在处理多个subplot时这样也更清楚一些)。当然你完全可以选择自己觉得方便的那个。

设置标题、轴标签、刻度以及刻度标签

为了说明自定义轴,我将创建一个简单的图像并绘制一段随机漫步,如下图所示:

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.random.randn(1000).cumsum())

Matplotlib 入门

要改变x轴刻度,最简单的办法是使用set_xticksset_xticklabels。前者告诉matplotlib要将刻度放在数据范围中的哪些位置,默认情况下,这些位置也就是刻度标签。但我们可以通过set_xticklabels将任何其他的值用作标签:

ticks = ax.set_xticks([0, 250, 500, 750, 1000])
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small')

rotation选项设定x刻度标签倾斜30度。最后,再用set_xlabel为X轴设置一个名称,并用set_title设 置一个标题,如下图所示:

ax.set_title('我的第一张matplotlib图')
ax.set_xlabel('阶段')

Matplotlib 入门

Y轴的修改方式与此类似,只需将上述代码中的x替换为y即可。轴的类有集合方法,可以批量设定绘图选项。前面的例子,也可以写为:

props = {
'title': '我的第一张matplotlib图',
'xlabel': '阶段'
}
ax.set(**props)

添加图例

图例(legend)是另一种用于标识图表元素的重要工具。添加图例的方式有多种。最简单的是在添加subplot的时候传入label参数:

from numpy.random import randn
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(1000).cumsum(), 'k', label='one')
ax.plot(randn(1000).cumsum(), 'k--', label='two')
ax.plot(randn(1000).cumsum(), 'k.', label='three')

在此之后,你可以调用ax.legend()plt.legend()来自动创建图例,结果如下图所示:

ax.legend(loc='best')

Matplotlib 入门

legend方法有几个其它的loc位置参数选项。可以查看文档字符串。

loc告诉matplotlib要将图例放在哪。如果你不是吹毛求疵的话,"best"是不错的选择,因为它会选择最不碍事的位置。要从图例中去除一个或多个元素,不传入label或传入label='nolegend’即可。(中文 第一版这里把best错写成了beat)。

注解以及在Subplot上绘图

除标准的绘图类型,你可能还希望绘制一些子集的注解,可能是文本、箭头或其他图形等。注解和 文字可以通过textarrowannotate函数进行添加。text可以将文本绘制在图表的指定坐标(x,y),还可以加上一些自定义格式:

ax.text(x, y, 'Hello world!',family='monospace', fontsize=10)

注解中可以既含有文本也含有箭头。例如,我们根据最近的标准普尔500指数价格(来自 Yahoo!Finance)绘制一张曲线图,并标出2008年到2009年金融危机期间的一些重要日期。你可以在 Jupyter notebook的一个小窗中试验这段代码,如下图所示:

from datetime import datetimefig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
data = pd.read_csv("../data/ch09/stock_px.csv", index_col=0, parse_dates=True)
spx = data['SPX']
spx.plot(ax=ax, style='k-')
crisis_data = [(datetime(2007, 10, 11), 'Peak of bull market'),(datetime(2008, 3, 12), 'Bear Stearns Fails'),(datetime(2008, 9, 15), 'Lehman Bankruptcy')
]
for date, label in crisis_data:ax.annotate(label, xy=(date, spx.asof(date) + 75),xytext=(date, spx.asof(date) + 225),arrowprops=dict(facecolor='black', headwidth=4, width=2,headlength=4),horizontalalignment='left', verticalalignment='top')
# Zoom in on 2007-2010
ax.set_xlim(['1/1/2007', '1/1/2011'])
ax.set_ylim([600, 1800])
ax.set_title('Important dates in the 2008-2009 financial crisis')

Matplotlib 入门

这张图中有几个重要的点要强调:ax.annotate方法可以在指定的xy坐标轴绘制标签。我们使用 set_xlimset_ylim人工设定起始和结束边界,而不使用matplotlib的默认方法。最后,用ax.set_title添 加图标标题。

图形的绘制要麻烦一些。matplotlib有一些表示常见图形的对象。这些对象被称为块(patch)。其 中有些(如Rectangle和Circle),可以在matplotlib.pyplot中找到,但完整集合位于 matplotlib.patches。 要在图表中添加一个图形,你需要创建一个块对象shp,然后通过ax.add_patch(shp)将其添加到 subplot中,如下图所示:

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
rect = plt.Rectangle((0.2, 0.75), 0.4, 0.15, color='k', alpha=0.3)
circ = plt.Circle((0.7, 0.2), 0.15, color='b', alpha=0.3)
pgon = plt.Polygon([[0.15, 0.15], [0.35, 0.4], [0.2, 0.6]],color='g', alpha=0.5)
ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)

Matplotlib 入门

如果查看许多常见图表对象的具体实现代码,你就会发现它们其实就是由块patch组装而成的。

将图表保存到文件

利用plt.savefig可以将当前图表保存到文件。该方法相当于Figure对象的实例方法savefig。例如, 要将图表保存为SVG文件,你只需输入:

plt.savefig('figpath.svg')

文件类型是通过文件扩展名推断出来的。因此,如果你使用的是.pdf,就会得到一个PDF文件。我 在发布图片时最常用到两个重要的选项是dpi(控制“每英寸点数”分辨率)和bbox_inches(可以剪除当 前图表周围的空白部分)。要得到一张带有最小白边且分辨率为400DPI的PNG图片,你可以:

plt.savefig('figpath.png', dpi=400, bbox_inches='tight'

savefig并非一定要写入磁盘,也可以写入任何文件型的对象,比如BytesIO:

from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()

下表列出了savefig的其他选项。

参数 说明
fname 含有文件路径的字符串或Python的文件型对象,图像格式由文件扩展名推断得出,例如,.pdf推断出PDF,.png推断出PNG
dpi 图像分辨率(每英寸点数),默认为100
facecoloredgecolor 图像的背景色,默认为“w”(白色)
format 显示设置文件格式(”png“,“pdf”,“svg”,…)
bbox_inches 图表需要保存的部分,如果设置为“tight”,则将尝试剪除图表周围的空白部分

matplotlib配置

matplotlib自带一些配色方案,以及为生成出版质量的图片而设定的默认配置信息。幸运的是,几 乎所有默认行为都能通过一组全局参数进行自定义,它们可以管理图像大小、subplot边距、配色方案、 字体大小、网格类型等。一种Python编程方式配置系统的方法是使用rc方法。例如,要将全局的图像默 认大小设置为10×10,你可以执行:

plt.rc('figure', figsize=(10, 10))

rc的第一个参数是希望自定义的对象,如’figure’、‘axes’、‘xtick’、‘ytick’、‘grid’、'legend’等。其后可以跟上一系列的关键字参数。一个简单的办法是将这些选项写成一个字典:

font_options = {'family' : 'monospace','weight' : 'bold','size' : 'small'}
plt.rc('font', **font_options)

要了解全部的自定义选项,可以查阅matplotlib的配置文件matplotlibrc(位于matplotlib/mpl-data 目录中)。如果对该文件进行了自定义,并将其放在你自己的.matplotlibrc目录中,则每次使用 matplotlib时就会加载该文件。