注意
跳转至页面底部下载完整示例代码。
快速入门指南#
本教程涵盖了一些基本的使用模式和最佳实践,旨在帮助您开始使用 Matplotlib。
import matplotlib.pyplot as plt
import numpy as np
一个简单的示例#
Matplotlib 在 Figure(例如窗口、Jupyter 小部件等)上绘制数据,每个 Figure 可以包含一个或多个 Axes。Axes 是一个区域,其中的点可以根据 x-y 坐标(或者极坐标图中的 theta-r,3D 图中的 x-y-z 等)进行指定。创建带有 Axes 的 Figure 最简单的方法是使用 pyplot.subplots。然后,我们可以使用 Axes.plot 在 Axes 上绘制数据,并使用 show 显示图形。
fig, ax = plt.subplots() # Create a figure containing a single Axes.
ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plot some data on the Axes.
plt.show() # Show the figure.

根据您工作的环境,有时可以省略 plt.show()。例如在 Jupyter notebook 中,代码单元格中创建的所有图形都会自动显示。
Figure 的组成部分#
以下是 Matplotlib Figure 的各个组成部分。
Figure#
整个图形。Figure 会跟踪所有的子 Axes、一组“特殊”的美工对象(Artists,如标题、图例、颜色条等),甚至是嵌套的子图。
通常,您可以通过以下函数之一创建一个新的 Figure:
fig = plt.figure() # an empty figure with no Axes
fig, ax = plt.subplots() # a figure with a single Axes
fig, axs = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes
# a figure with one Axes on the left, and two on the right:
fig, axs = plt.subplot_mosaic([['left', 'right_top'],
['left', 'right_bottom']])
subplots() 和 subplot_mosaic 是便捷函数,它们会在 Figure 内部额外创建 Axes 对象,但您也可以稍后手动添加 Axes。
有关 Figures 的更多信息(包括平移和缩放),请参阅 Figure 简介。
Axes#
Axes 是附加到 Figure 上的一个美工对象(Artist),包含一个用于绘制数据的区域,通常包括两个(3D 情况为三个)Axis 对象(请注意 Axes 和 Axis 之间的区别),这些对象提供刻度和刻度标签,为 Axes 中的数据提供刻度。每个 Axes 都有一个标题(通过 set_title() 设置)、x 轴标签(通过 set_xlabel() 设置)和 y 轴标签(通过 set_ylabel() 设置)。
Axes 方法是配置绘图大部分内容(添加数据、控制坐标轴缩放和范围、添加标签等)的主要接口。
Axis#
这些对象设置缩放比例和限制,并生成刻度(Axis 上的标记)和刻度标签(标记刻度的字符串)。刻度的位置由 Locator 对象决定,刻度标签字符串由 Formatter 格式化。正确的 Locator 和 Formatter 的组合可以对刻度位置和标签进行非常精细的控制。
Artist#
基本上,Figure 上可见的所有内容都是一个 Artist(甚至是 Figure、Axes 和 Axis 对象)。这包括 Text 对象、Line2D 对象、collections 对象、Patch 对象等。当 Figure 被渲染时,所有的 Artists 都会被绘制到画布(canvas)上。大多数 Artists 都绑定到一个 Axes;这样的 Artist 不能被多个 Axes 共享,也不能从一个 Axes 移动到另一个。
绘图函数的输入类型#
绘图函数期望 numpy.array 或 numpy.ma.masked_array 作为输入,或者可以传递给 numpy.asarray 的对象。类似于数组的类('array-like'),例如 pandas 数据对象和 numpy.matrix 可能无法按预期工作。常见的约定是在绘图之前将它们转换为 numpy.array 对象。
b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)
大多数方法还可以解析可字符串索引的对象,如 dict、结构化 numpy 数组或 pandas.DataFrame。Matplotlib 允许您提供 data 关键字参数,并通过传递与 x 和 y 变量对应的字符串来生成图表。
np.random.seed(19680801) # seed the random number generator.
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
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.scatter('a', 'b', c='c', s='d', data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b')

编码风格#
显式接口与隐式接口#
如上所述,使用 Matplotlib 本质上有两种方式:
显式创建 Figures 和 Axes,并调用它们的方法(“面向对象 (OO) 风格”)。
依靠 pyplot 隐式创建和管理 Figures 和 Axes,并使用 pyplot 函数进行绘图。
请参阅 Matplotlib 应用程序接口 (APIs),了解隐式接口和显式接口之间权衡的解释。
因此,可以使用面向对象风格:
x = np.linspace(0, 2, 100) # Sample data.
# Note that even in the OO-style, we use `.pyplot.figure` to create the Figure.
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear') # Plot some data on the Axes.
ax.plot(x, x**2, label='quadratic') # Plot more data on the Axes...
ax.plot(x, x**3, label='cubic') # ... and some more.
ax.set_xlabel('x label') # Add an x-label to the Axes.
ax.set_ylabel('y label') # Add a y-label to the Axes.
ax.set_title("Simple Plot") # Add a title to the Axes.
ax.legend() # Add a legend.

或者 pyplot 风格:
x = np.linspace(0, 2, 100) # Sample data.
plt.figure(figsize=(5, 2.7), layout='constrained')
plt.plot(x, x, label='linear') # Plot some data on the (implicit) Axes.
plt.plot(x, x**2, label='quadratic') # etc.
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()

(此外,还有第三种方法,适用于将 Matplotlib 嵌入到 GUI 应用程序中的情况,这种方法完全摒弃了 pyplot,甚至在创建图形时也是如此。更多信息请参阅示例库中的相应部分:在图形用户界面中嵌入 Matplotlib。)
Matplotlib 的文档和示例同时使用了面向对象风格和 pyplot 风格。通常,我们建议使用面向对象风格,特别是对于复杂的图形,以及打算作为大型项目一部分复用的函数和脚本。然而,pyplot 风格对于快速交互式工作非常方便。
注意
您可能会发现一些使用 pylab 接口的旧示例(通过 from pylab import *)。这种方法已被强烈弃用。
编写辅助函数#
如果您需要使用不同的数据集反复制作相同的图表,或者想要轻松封装 Matplotlib 方法,请使用下面推荐的函数签名。
您可以调用此函数两次来填充两个子图。

请注意,如果您想将这些安装为 python 包,或者进行任何其他自定义,可以使用网络上的众多模板之一;Matplotlib 提供了一个模板:mpl-cookiecutter。
美化 Artist 对象#
大多数绘图方法都有针对 Artist 的样式选项,可以在调用绘图方法时访问,也可以通过 Artist 上的“setter”方法访问。在下面的绘图中,我们手动设置了由 plot 创建的 Artist 的 color、linewidth 和 linestyle,并随后使用 set_linestyle 设置了第二条线的线型。

颜色#
Matplotlib 为大多数 Artist 提供了非常灵活的颜色选择;有关规格列表,请参阅 允许的颜色定义。一些 Artist 可以接受多种颜色,例如在 scatter 散点图中,标记的边缘颜色可以与内部颜色不同。
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='C0', edgecolor='k')

线宽、线型和标记大小#
线宽通常以排版点(1 pt = 1/72 英寸)为单位,适用于具有线条的 Artist。类似地,线条可以具有线型。请参阅 线型示例。
标记大小取决于所使用的方法。plot 以点为单位指定标记大小,通常是标记的“直径”或宽度。scatter 将标记大小指定为大致与标记的视觉面积成比例。有多种可用的字符串代码标记样式(请参阅 markers),或者用户可以定义自己的 MarkerStyle(请参阅 标记参考)。

标记图表#
坐标轴标签和文本#
set_xlabel、set_ylabel 和 set_title 用于在指定位置添加文本(更多讨论请参阅 Matplotlib 中的文本)。文本也可以使用 text 直接添加到图表中。
mu, sigma = 115, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
# the histogram of the data
n, bins, patches = ax.hist(x, 50, density=True, facecolor='C0', alpha=0.75)
ax.set_xlabel('Length [cm]')
ax.set_ylabel('Probability')
ax.set_title('Aardvark lengths\n (not really)')
ax.text(75, .025, r'$\mu=115,\ \sigma=15$')
ax.axis([55, 175, 0, 0.03])
ax.grid(True)

所有的 text 函数都会返回一个 matplotlib.text.Text 实例。正如上面的线条一样,您可以通过向文本函数传递关键字参数来自定义属性。
t = ax.set_xlabel('my data', fontsize=14, color='red')
这些属性在 文本属性和布局 中有更详细的介绍。
在文本中使用数学表达式#
Matplotlib 接受任何文本表达式中的 TeX 方程表达式。例如,要在标题中编写表达式 \(\sigma_i=15\),您可以编写一个用美元符号括起来的 TeX 表达式。
ax.set_title(r'$\sigma_i=15$')
标题字符串前的 r 表示该字符串是 raw 字符串,不应将反斜杠视为 python 转义字符。Matplotlib 具有内置的 TeX 表达式解析器和布局引擎,并附带了自己的数学字体——详细信息请参阅 编写数学表达式。您还可以直接使用 LaTeX 来格式化文本,并将输出直接集成到您的显示图形或保存的 postscript 中——请参阅 使用 LaTeX 渲染文本。
注释#
我们还可以注释图表上的点,通常通过连接指向 xy 的箭头到 xytext 处的文本。
fig, ax = plt.subplots(figsize=(5, 2.7))
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2 * np.pi * t)
line, = ax.plot(t, s, lw=2)
ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05))
ax.set_ylim(-2, 2)

在这个基本示例中,xy 和 xytext 都在数据坐标中。您可以选择多种其他坐标系——详细信息请参阅 基本注释 和 高级注释。更多示例可以在 注释图表 中找到。
图例#
通常我们希望使用 Axes.legend 来标识线条或标记。

Matplotlib 中的图例在布局、放置和它们可以表示的 Artist 类型方面非常灵活。它们在 图例指南 中有详细讨论。
坐标轴缩放和刻度#
每个 Axes 有两个(或三个)Axis 对象,分别表示 x 轴和 y 轴。它们控制 Axis 的 缩放、刻度 定位器 (locators) 和刻度 格式化程序 (formatters)。可以附加额外的 Axes 来显示更多的 Axis 对象。
刻度#
除了线性缩放外,Matplotlib 还提供非线性缩放,例如对数缩放。由于对数缩放使用非常频繁,因此还有 loglog、semilogx 和 semilogy 等直接方法。还有许多其他缩放比例(其他示例请参阅 缩放比例概述)。在这里我们手动设置缩放。

缩放设置了从数据值到沿 Axis 间距的映射。这在两个方向上都会发生,并组合成一个 变换 (transform),这是 Matplotlib 将数据坐标映射到 Axes、Figure 或屏幕坐标的方式。请参阅 变换教程。
刻度定位器和格式化程序#
每个 Axis 都有一个刻度 定位器 (locator) 和 格式化程序 (formatter),它们决定了在 Axis 对象的哪个位置放置刻度标记。一个简单的接口是 set_xticks。
fig, axs = plt.subplots(2, 1, layout='constrained')
axs[0].plot(xdata, data1)
axs[0].set_title('Automatic ticks')
axs[1].plot(xdata, data1)
axs[1].set_xticks(np.arange(0, 100, 30), ['zero', '30', 'sixty', '90'])
axs[1].set_yticks([-1.5, 0, 1.5]) # note that we don't need to specify labels
axs[1].set_title('Manual ticks')

不同的缩放比例可以使用不同的定位器和格式化程序;例如,上面的对数缩放使用了 LogLocator 和 LogFormatter。有关其他格式化程序和定位器以及编写自己的方法的信息,请参阅 刻度定位器 和 刻度格式化程序。
绘制日期和字符串#
Matplotlib 可以处理绘制日期数组和字符串数组,以及浮点数。这些会根据需要使用特殊的定位器和格式化程序。对于日期:
from matplotlib.dates import ConciseDateFormatter
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
dates = np.arange(np.datetime64('2021-11-15'), np.datetime64('2021-12-25'),
np.timedelta64(1, 'h'))
data = np.cumsum(np.random.randn(len(dates)))
ax.plot(dates, data)
ax.xaxis.set_major_formatter(ConciseDateFormatter(ax.xaxis.get_major_locator()))

有关更多信息,请参阅日期示例(例如 日期刻度标签)。
对于字符串,我们将获得分类绘图(请参阅:绘制分类变量)。
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
categories = ['turnips', 'rutabaga', 'cucumber', 'pumpkins']
ax.bar(categories, np.random.rand(len(categories)))

关于分类绘图的一个警告是,某些解析文本文件的方法会返回字符串列表,即使这些字符串都代表数字或日期。如果您传递 1000 个字符串,Matplotlib 会认为您的意思是 1000 个类别,并会在您的图表上添加 1000 个刻度!
额外的 Axis 对象#
在同一个图表中绘制不同量级的数据可能需要一个额外的 y 轴。这样的 Axis 可以通过使用 twinx 来创建一个新的 Axes,该 Axes 具有一个不可见的 x 轴和一个位于右侧的 y 轴(twiny 同理)。另一个示例请参阅 具有不同比例的图表。
类似地,您可以添加一个 secondary_xaxis 或 secondary_yaxis,其缩放比例与主 Axis 不同,以便以不同的缩放比例或单位表示数据。更多示例请参阅 二级坐标轴。
fig, (ax1, ax3) = plt.subplots(1, 2, figsize=(7, 2.7), layout='constrained')
l1, = ax1.plot(t, s)
ax2 = ax1.twinx()
l2, = ax2.plot(t, range(len(t)), 'C1')
ax2.legend([l1, l2], ['Sine (left)', 'Straight (right)'])
ax3.plot(t, s)
ax3.set_xlabel('Angle [rad]')
ax4 = ax3.secondary_xaxis('top', (np.rad2deg, np.deg2rad))
ax4.set_xlabel('Angle [°]')

颜色映射数据#
通常我们希望在图表中用颜色映射来表示第三个维度。Matplotlib 有许多实现此目的的图表类型:
from matplotlib.colors import LogNorm
X, Y = np.meshgrid(np.linspace(-3, 3, 128), np.linspace(-3, 3, 128))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
fig, axs = plt.subplots(2, 2, layout='constrained')
pc = axs[0, 0].pcolormesh(X, Y, Z, vmin=-1, vmax=1, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[0, 0])
axs[0, 0].set_title('pcolormesh()')
co = axs[0, 1].contourf(X, Y, Z, levels=np.linspace(-1.25, 1.25, 11))
fig.colorbar(co, ax=axs[0, 1])
axs[0, 1].set_title('contourf()')
pc = axs[1, 0].imshow(Z**2 * 100, cmap='plasma', norm=LogNorm(vmin=0.01, vmax=100))
fig.colorbar(pc, ax=axs[1, 0], extend='both')
axs[1, 0].set_title('imshow() with LogNorm()')
pc = axs[1, 1].scatter(data1, data2, c=data3, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[1, 1], extend='both')
axs[1, 1].set_title('scatter()')

颜色映射 (Colormaps)#
这些都是派生自 ScalarMappable 对象的 Artist 示例。它们都可以设置 vmin 和 vmax 之间的线性映射到由 cmap 指定的颜色映射中。Matplotlib 有许多颜色映射可供选择(在 Matplotlib 中选择颜色映射),您可以创建自己的(在 Matplotlib 中创建颜色映射),或者作为 第三方包 下载。
归一化 (Normalizations)#
有时我们需要对数据进行非线性映射到颜色映射,如上面的 LogNorm 示例。我们通过向 ScalarMappable 提供 norm 参数而不是 vmin 和 vmax 来实现这一点。更多归一化示例请参阅 颜色映射归一化。
颜色条 (Colorbars)#
添加一个 colorbar 提供了一个将颜色关联回底层数据的键。颜色条是图形级别的 Artist,并附加到 ScalarMappable 上(它们从中获取关于归一化和颜色映射的信息),并且通常从父 Axes 中占用空间。颜色条的放置可能很复杂:详情请参阅 放置颜色条。您还可以使用 extend 关键字来添加箭头,使用 shrink 和 aspect 来控制大小,从而改变颜色条的外观。最后,颜色条将具有适合归一化的默认定位器和格式化程序。这些可以像其他 Axis 对象一样进行更改。
使用多个 Figure 和 Axes#
您可以通过多次调用 fig = plt.figure() 或 fig2, ax = plt.subplots() 来打开多个 Figure。通过保留对象引用,您可以向任一 Figure 添加 Artist。
可以通过多种方式添加多个 Axes,但最基本的是上面使用的 plt.subplots()。可以使用 subplot_mosaic 实现更复杂的布局,使 Axes 对象跨越列或行。

Matplotlib 拥有非常复杂的工具来排列 Axes:请参阅 在 Figure 中排列多个 Axes 和 复杂且语义化的图形组合 (subplot_mosaic)。
更多阅读#
有关更多绘图类型,请参阅 绘图类型 和 API 参考,特别是 Axes API。
脚本总运行时间:(0 分钟 6.395 秒)