快速入门指南#

本教程涵盖了一些基本的使用模式和最佳实践,以帮助您开始使用 Matplotlib。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

一个简单的例子#

Matplotlib 将您的数据绘制在Figures 上(例如,windows、Jupyter 小部件等),其中每个都可以包含一个或多个Axes,一个可以根据 xy 坐标(或极坐标图中的 theta-r,xyz)指定点的区域在 3D 图中等)。使用 Axes 创建图形的最简单方法是使用pyplot.subplots. 然后我们可以使用 Axes.plot在轴上绘制一些数据:

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.
快速开始
[<matplotlib.lines.Line2D object at 0x7f2cdf586e60>]

图的部分#

这是 Matplotlib 图的组成部分。

../../_images/anatomy.png

Figure#

整个。Figure 跟踪所有 child Axes、一组“特殊”艺术家(标题、图形图例、颜色条等),甚至嵌套子图形。

创建新图形的最简单方法是使用 pyplot:

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

与图形一起创建轴通常很方便,但您也可以稍后手动添加轴。请注意,许多 Matplotlib 后端支持在图形窗口上进行缩放和平移。

Axes#

Axes 是附加到包含用于绘制数据的区域的图形的艺术家,通常包括两个(或在 3D 的情况下为三个) 对象(注意AxesAxisAxis之间的区别),它们提供刻度和刻度标签以提供坐标轴中数据的比例。每个都有一个标题(通过 设置)、一个 x-标签(通过 设置 )和一个 y-标签通过 设置 。Axesset_title()set_xlabel()set_ylabel()

Axes及其成员函数是使用 OOP 接口的主要入口点,并在其上定义了大多数绘图方法(例如ax.plot(),如上所示,使用该plot方法)

Axis#

这些对象设置比例和限制并生成刻度(轴上的标记)和刻度标签(标记刻度的字符串)。刻度的位置由Locator对象确定,刻度标签字符串由Formatter. Locator正确的组合可以Formatter很好地控制刻度位置和标签。

Artist#

基本上,图形上可见的所有内容都是艺术家(甚至 FigureAxesAxis对象)。这包括 Text物件、Line2D物件、collections物件、Patch 物件等。当图形被渲染时,所有的艺术家都被绘制到画布上。大多数艺术家都被绑在轴上;这样的艺术家不能被多个轴共享,也不能从一个轴移动到另一个轴。

绘图函数的输入类型#

绘图函数期望numpy.arraynumpy.ma.masked_array作为输入,或可以传递给的对象numpy.asarray。类似于数组(“类数组”)的类,例如pandas 数据对象,numpy.matrix可能无法按预期工作。常见的约定是numpy.array在绘图之前将它们转换为对象。例如,要转换一个numpy.matrix

b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)

大多数方法还将解析可寻址对象,如dict、 a numpy.recarray或 a pandas.DataFrame。Matplotlib 允许您提供关键字参数并生成传递与xy变量data对应的字符串的图。

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');
快速开始
Text(36.334, 0.5, 'entry b')

编码风格#

显式和隐式接口#

如上所述,基本上有两种使用 Matplotlib 的方法:

  • 显式创建图形和轴,并在它们上调用方法(“面向对象 (OO) 样式”)。

  • 依靠 pyplot 隐式创建和管理图形和轴,并使用 pyplot 函数进行绘图。

有关隐式和显式接口之间权衡的解释,请参阅Matplotlib 应用程序接口 (API)

所以可以使用 OO 风格

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.
简单情节
<matplotlib.legend.Legend object at 0x7f2cdf587f70>

或 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.legend.Legend object at 0x7f2cfa992cb0>

(此外,还有第三种方法,在将 Matplotlib 嵌入 GUI 应用程序的情况下,它完全放弃了 pyplot,即使是用于图形创建也是如此。有关更多信息,请参阅图库中的相应部分: 在图形用户界面中嵌入 Matplotlib。)

Matplotlib 的文档和示例同时使用 OO 和 pyplot 样式。一般来说,我们建议使用 OO 风格,特别是对于复杂的绘图,以及旨在作为更大项目的一部分重用的函数和脚本。但是,pyplot 样式可以非常方便地进行快速交互工作。

笔记

您可以通过 找到使用该pylab接口的旧示例。这种方法被强烈反对。from pylab import *

制作辅助函数#

如果您需要使用不同的数据集一遍又一遍地绘制相同的图,或者想要轻松包装 Matplotlib 方法,请使用下面推荐的签名函数。

def my_plotter(ax, data1, data2, param_dict):
    """
    A helper function to make a graph.
    """
    out = ax.plot(data1, data2, **param_dict)
    return out

然后您将使用它两次来填充两个子图:

data1, data2, data3, data4 = np.random.randn(4, 100)  # make 4 random data sets
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.7))
my_plotter(ax1, data1, data2, {'marker': 'x'})
my_plotter(ax2, data3, data4, {'marker': 'o'});
快速开始
[<matplotlib.lines.Line2D object at 0x7f2cddab7c10>]

请注意,如果您想将它们安装为 python 包或任何其他自定义项,您可以使用网络上的众多模板之一;Matplotlib 在mpl- cookiecutter 有一个

造型师#

大多数绘图方法都有 Artists 的样式选项,可以在调用绘图方法时访问,也可以从 Artist 上的“setter”访问。在下图中,我们手动设置了由 创建的 Artists的颜色线宽线型plot,我们用 设置了事后第二行的线型set_linestyle

fig, ax = plt.subplots(figsize=(5, 2.7))
x = np.arange(len(data1))
ax.plot(x, np.cumsum(data1), color='blue', linewidth=3, linestyle='--')
l, = ax.plot(x, np.cumsum(data2), color='orange', linewidth=2)
l.set_linestyle(':');
快速开始

颜色#

Matplotlib 有一个非常灵活的颜色数组,大多数艺术家都可以接受;有关规格列表,请参阅颜色教程。一些艺术家会采用多种颜色。即对于scatter情节,标记的边缘可以是与内部不同的颜色:

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='C0', edgecolor='k');
快速开始
<matplotlib.collections.PathCollection object at 0x7f2cddcf8280>

线宽、线型和标记大小#

线宽通常以印刷点为单位(1 pt = 1/72 英寸),适用于有描边线的艺术家。类似地,描边线可以具有线型。请参阅线条样式示例

标记大小取决于所使用的方法。plot以点为单位指定标记大小,通常是标记的“直径”或宽度。scatter将标记大小指定为与标记的可视区域大致成比例。有一系列可用作字符串代码的标记样式(参见 参考资料markers),或者用户可以定义自己的标记样式MarkerStyle(参见 标记参考):

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(data1, 'o', label='data1')
ax.plot(data2, 'd', label='data2')
ax.plot(data3, 'v', label='data3')
ax.plot(data4, 's', label='data4')
ax.legend();
快速开始
<matplotlib.legend.Legend object at 0x7f2cfa946650>

标记地块#

轴标签和文本#

set_xlabel, set_ylabel, 和set_title用于在指定位置添加文本( 有关更多讨论,请参见Matplotlib Plots中的文本)。也可以使用以下方法将文本直接添加到绘图中 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前面的标题字符串表示该字符串是 原始字符串,并且不将反斜杠视为 python 转义。Matplotlib 有一个内置的 TeX 表达式解析器和布局引擎,并提供自己的数学字体——有关详细信息,请参阅 编写数学表达式。您还可以直接使用 LaTeX 来格式化您的文本并将输出直接合并到您的显示图形或保存的后记中 - 请参阅Text rendering with 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);
快速开始
(-2.0, 2.0)

在这个基本示例中,xyxytext都在数据坐标中。有多种其他坐标系可供选择——有关详细信息,请参阅 基本注释高级注释。更多示例也可以在 Annotating Plots中找到。

传说#

通常我们想用 来识别线条或标记Axes.legend

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(np.arange(len(data1)), data1, label='data1')
ax.plot(np.arange(len(data2)), data2, label='data2')
ax.plot(np.arange(len(data3)), data3, 'd', label='data3')
ax.legend();
快速开始
<matplotlib.legend.Legend object at 0x7f2cde2aaa40>

Matplotlib 中的图例在布局、放置以及它们可以代表的艺术家方面非常灵活。在Legend 指南中详细讨论了它们 。

轴刻度和刻度#

每个 Axes 都有两个(或三个)Axis表示 x 轴和 y 轴的对象。这些控制轴的比例、刻度定位器和刻度格式化程序。可以附加附加轴以显示更多轴对象。

#

除了线性刻度,Matplotlib 还提供非线性刻度,例如对数刻度。由于使用了如此多的对数刻度,因此也有直接的方法,如loglogsemilogxsemilogy。有许多尺度(有关其他示例,请参见 尺度)。这里我们手动设置比例:

fig, axs = plt.subplots(1, 2, figsize=(5, 2.7), layout='constrained')
xdata = np.arange(len(data1))  # make an ordinal for this
data = 10**data1
axs[0].plot(xdata, data)

axs[1].set_yscale('log')
axs[1].plot(xdata, data);
快速开始
[<matplotlib.lines.Line2D object at 0x7f2cde4a5930>]

比例设置从数据值到沿轴的间距的映射。这发生在两个方向上,并被组合成一个transform,这是 Matplotlib 从数据坐标映射到 Axes、Figure 或屏幕坐标的方式。请参阅转换教程

刻度定位器和格式化程序#

每个 Axis 都有一个刻度定位器格式化程序,它们可以选择沿着 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');
自动刻度,手动刻度
Text(0.5, 1.0, 'Manual ticks')

不同的比例可以有不同的定位器和格式化器;例如上面的对数刻度使用LogLocatorLogFormatter。有关其他格式化程序和定位器以及编写您自己的信息的信息,请参阅 刻度定位器刻度格式化程序。

绘制日期和字符串#

Matplotlib 可以处理日期数组和字符串数组以及浮点数的绘图。这些会根据需要获得特殊的定位器和格式化程序。对于日期:

快速开始

有关更多信息,请参阅日期示例(例如日期刻度标签

对于字符串,我们得到分类绘图(请参阅: 绘制分类变量)。

fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
categories = ['turnips', 'rutabaga', 'cucumber', 'pumpkins']

ax.bar(categories, np.random.rand(len(categories)));
快速开始
<BarContainer object of 4 artists>

关于分类绘图的一个警告是,一些解析文本文件的方法会返回一个字符串列表,即使这些字符串都表示数字或日期。如果您传递 1000 个字符串,Matplotlib 会认为您的意思是 1000 个类别,并会在您的绘图中添加 1000 个刻度!

附加轴对象#

在一个图表中绘制不同大小的数据可能需要额外的 y 轴。可以通过使用 twinx添加一个新的轴来创建这样的轴,该轴具有不可见的 x 轴和位于右侧的 y 轴(类似于twiny)。有关另一个示例,请参见 具有不同比例的图。

类似地,您可以添加secondary_xaxissecondary_yaxis具有与主轴不同的比例来表示不同比例或单位的数据。有关更多示例,请参见 辅助轴

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', functions=(np.rad2deg, np.deg2rad))
ax4.set_xlabel('Angle [°]')
快速开始
Text(0.5, 509.6660000000001, 'Angle [°]')

颜色映射数据#

通常,我们希望在由颜色图中的颜色表示的图中具有第三维。Matplotlib 有许多执行此操作的绘图类型:

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=mpl.colors.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()')
pcolormesh()、contourf()、imshow() 和 LogNorm()、scatter()
Text(0.5, 1.0, 'scatter()')

颜色图#

这些都是从ScalarMappable 对象派生的艺术家的例子。他们都可以将vminvmax之间的线性映射设置为cmap指定的颜色映射。Matplotlib 有许多颜色图可供选择(在 Matplotlib中选择颜色图),您可以自己制作(在 Matplotlib 中创建颜色图)或作为 第三方包下载。

规范化#

有时我们希望数据到颜色图的非线性映射,如上LogNorm例所示。我们通过为 ScalarMappable 提供norm参数而不是vminvmax来做到这一点。更多规范化显示在Colormap Normalization

颜色条#

添加 acolorbar可以将颜色与基础数据相关联。颜色条是图形级别的艺术家,并附加到 ScalarMappable(它们在其中获取有关规范和颜色图的信息),并且通常从父 Axes 中窃取空间。颜色条的放置可能很复杂:有关详细信息,请参阅 放置颜色条。您还可以使用 extend关键字更改颜色条的外观以在末端添加箭头,并通过缩小纵横比来控制大小。最后,颜色条将具有适合规范的默认定位器和格式化程序。这些可以像其他 Axis 对象一样更改。

使用多个图形和轴#

您可以通过多次调用 或来打开多个图形。通过保留对象引用,您可以将艺术家添加到任一图形。fig = plt.figure()fig2, ax = plt.subplots()

可以通过多种方式添加多个轴,但最基本的方法 plt.subplots()如上所示。使用subplot_mosaic.

fig, axd = plt.subplot_mosaic([['upleft', 'right'],
                               ['lowleft', 'right']], layout='constrained')
axd['upleft'].set_title('upleft')
axd['lowleft'].set_title('lowleft')
axd['right'].set_title('right');
左上,右,左下
Text(0.5, 1.0, 'right')

Matplotlib 具有用于排列轴的非常复杂的工具:请参阅 Arrangeing multiple Axes in a FigureComplex and semantic figure composition

更多阅读#

有关更多绘图类型,请参阅绘图类型API 参考,尤其是 Axes API

脚本总运行时间:(0分9.122秒)

由 Sphinx-Gallery 生成的画廊