Pyplot 教程#

Pyplot 接口的介绍。请参阅 快速入门指南 了解 Matplotlib 的工作原理概述,以及 Matplotlib 应用程序接口 (API) 了解支持的用户 API 之间的权衡。

Pyplot 简介#

matplotlib.pyplot 是一个函数集合,使 Matplotlib 的工作方式类似于 MATLAB。每个 pyplot 函数都会对图形进行一些更改:例如,创建图形、在图形中创建绘图区域、在绘图区域中绘制一些线条、用标签装饰绘图等。

matplotlib.pyplot 中,各种状态在函数调用之间保持不变,因此它会跟踪诸如当前图形和绘图区域之类的信息,并且绘图函数会定向到当前 Axes(请注意,我们使用大写 Axes 来指代 Axes 概念,它是 图形的一部分,而不仅仅是 axis 的复数形式)。

注意

隐式 pyplot API 通常不太冗长,但也不如显式 API 灵活。这里看到的大多数函数调用也可以作为 Axes 对象的方法调用。建议浏览教程和示例以了解其工作原理。请参阅 Matplotlib 应用程序接口 (API),了解支持的用户 API 的权衡。

使用 pyplot 生成可视化非常快

import matplotlib.pyplot as plt

plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
pyplot

您可能想知道为什么 x 轴范围从 0 到 3,而 y 轴范围从 1 到 4。如果您向 plot 提供单个列表或数组,matplotlib 会假设它是一系列 y 值,并自动为您生成 x 值。由于 python 范围从 0 开始,因此默认的 x 向量与 y 的长度相同,但从 0 开始;因此,x 数据为 [0, 1, 2, 3]

plot 是一个多功能函数,可以接受任意数量的参数。例如,要绘制 x 与 y 的关系图,您可以编写

plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
pyplot

格式化绘图的样式#

对于每对 x、y 参数,都有一个可选的第三个参数,它是一个格式字符串,指示绘图的颜色和线型。格式字符串的字母和符号来自 MATLAB,您将颜色字符串与线型字符串连接起来。默认格式字符串为 'b-',表示实线蓝色。例如,要以红色圆圈绘制以上内容,您需要执行以下操作

plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')
plt.axis((0, 6, 0, 20))
plt.show()
pyplot

请参阅 plot 文档以获取线型和格式字符串的完整列表。上面示例中的 axis 函数接受 [xmin, xmax, ymin, ymax] 的列表,并指定 Axes 的视窗。

如果 matplotlib 仅限于使用列表,那么它对于数值处理将毫无用处。通常,您将使用 numpy 数组。实际上,所有序列在内部都会转换为 numpy 数组。以下示例说明了使用数组在一个函数调用中绘制具有不同格式样式的几条线。

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()
pyplot

使用关键字字符串绘图#

在某些情况下,您的数据格式允许您使用字符串访问特定变量。例如,使用 结构化数组pandas.DataFrame.

Matplotlib 允许您使用 data 关键字参数提供这样的对象。如果提供,则可以使用与这些变量相对应的字符串生成绘图。

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()
pyplot

使用分类变量绘图#

也可以使用分类变量创建绘图。Matplotlib 允许您将分类变量直接传递给许多绘图函数。例如

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()
Categorical Plotting

控制线属性#

线条有许多可以设置的属性:线宽、虚线样式、抗锯齿等;请参阅 matplotlib.lines.Line2D。有几种方法可以设置线属性

  • 使用关键字参数

    plt.plot(x, y, linewidth=2.0)
    
  • 使用 Line2D 实例的 setter 方法。 plot 返回一个 Line2D 对象列表;例如,line1, line2 = plot(x1, y1, x2, y2)。在下面的代码中,我们将假设我们只有一条线,因此返回的列表长度为 1。我们使用 line, 的元组解包来获取该列表的第一个元素

    line, = plt.plot(x, y, '-')
    line.set_antialiased(False) # turn off antialiasing
    
  • 使用 setp。下面的示例使用 MATLAB 风格的函数来设置线条列表上的多个属性。 setp 透明地使用对象列表或单个对象。您可以使用 python 关键字参数或 MATLAB 风格的字符串/值对

    lines = plt.plot(x1, y1, x2, y2)
    # use keyword arguments
    plt.setp(lines, color='r', linewidth=2.0)
    # or MATLAB style string value pairs
    plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
    

以下是可用的 Line2D 属性。

属性

值类型

alpha

浮点数

动画

[True | False]

抗锯齿或 aa

[True | False]

裁剪框

一个 matplotlib.transform.Bbox 实例

裁剪

[True | False]

裁剪路径

一个 Path 实例和一个 Transform 实例,一个 Patch

颜色或 c

任何 matplotlib 颜色

包含

命中测试函数

虚线端点样式

['butt' | 'round' | 'projecting']

虚线连接样式

['miter' | 'round' | 'bevel']

虚线

点单位的开/关墨水序列

数据

(np.array xdata, np.array ydata)

图形

一个 matplotlib.figure.Figure 实例

标签

任何字符串

线型或 ls

[ '-' | '--' | '-.' | ':' | 'steps' | ...]

线宽或 lw

点单位的浮点数

标记

[ '+' | ',' | '.' | '1' | '2' | '3' | '4' ]

标记边框颜色或 mec

任何 matplotlib 颜色

标记边框宽度或 mew

点单位的浮点数

标记填充颜色或 mfc

任何 matplotlib 颜色

标记大小或 ms

浮点数

标记间隔

[ None | 整数 | (startind, stride) ]

拾取器

用于交互式线选择

拾取半径

线拾取选择半径

实线端点样式

['butt' | 'round' | 'projecting']

实线连接样式

['miter' | 'round' | 'bevel']

变换

一个 matplotlib.transforms.Transform 实例

可见

[True | False]

xdata

np.array

ydata

np.array

zorder

任何数字

要获取可设置的线属性列表,请使用线或线作为参数调用 setp 函数

In [69]: lines = plt.plot([1, 2, 3])

In [70]: plt.setp(lines)
  alpha: float
  animated: [True | False]
  antialiased or aa: [True | False]
  ...snip

使用多个图形和坐标轴#

MATLAB 和 pyplot 有当前图形和当前坐标轴的概念。所有绘图函数都应用于当前坐标轴。函数 gca 返回当前坐标轴(一个 matplotlib.axes.Axes 实例),而 gcf 返回当前图形(一个 matplotlib.figure.Figure 实例)。通常,您不必担心这一点,因为所有这些都在幕后处理。以下是一个创建两个子图的脚本。

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()
pyplot

这里的 figure 调用是可选的,因为如果不存在图形,将会创建一个图形,就像如果不存在 Axes,将会创建一个 Axes(等同于显式 subplot() 调用)一样。 subplot 调用指定了 numrows, numcols, plot_number,其中 plot_number 的范围从 1 到 numrows*numcols。如果 numrows*numcols<10,则 subplot 调用中的逗号是可选的。因此,subplot(211) 等同于 subplot(2, 1, 1)

您可以创建任意数量的子图和 Axes。如果您想手动放置 Axes,即不在矩形网格上,请使用 axes,它允许您将位置指定为 axes([left, bottom, width, height]),其中所有值都以分数(0 到 1)坐标表示。有关手动放置 Axes 的示例,请参见 Axes 演示,有关大量子图的示例,请参见 多个子图

您可以通过使用多个 figure 调用并增加图形编号来创建多个图形。当然,每个图形都可以包含任意数量的 Axes 和子图,只要您愿意。

import matplotlib.pyplot as plt
plt.figure(1)                # the first figure
plt.subplot(211)             # the first subplot in the first figure
plt.plot([1, 2, 3])
plt.subplot(212)             # the second subplot in the first figure
plt.plot([4, 5, 6])


plt.figure(2)                # a second figure
plt.plot([4, 5, 6])          # creates a subplot() by default

plt.figure(1)                # first figure current;
                             # subplot(212) still current
plt.subplot(211)             # make subplot(211) in the first figure
                             # current
plt.title('Easy as 1, 2, 3') # subplot 211 title

您可以使用 clf 清除当前图形,使用 cla 清除当前 Axes。如果您发现幕后维护状态(特别是当前图像、图形和 Axes)很烦人,请不要绝望:这只是一个围绕面向对象 API 的轻量级有状态包装器,您可以使用它(参见 Artist 教程)。

如果您要创建大量图形,还需要注意一点:图形所需的内存只有在使用 close 显式关闭图形后才会完全释放。删除对图形的所有引用,或使用窗口管理器关闭图形窗口,都不足以释放内存,因为 pyplot 会在调用 close 之前保留内部引用。

使用文本#

text 可用于在任意位置添加文本,而 xlabelylabeltitle 用于在指定位置添加文本(有关更详细的示例,请参见 Matplotlib 中的文本)。

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=True, 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()
Histogram of IQ

所有 text 函数都返回一个 matplotlib.text.Text 实例。就像上面的线条一样,您可以通过将关键字参数传递给文本函数或使用 setp 来自定义属性。

t = plt.xlabel('my data', fontsize=14, color='red')

这些属性将在 文本属性和布局 中更详细地介绍。

在文本中使用数学表达式#

Matplotlib 接受任何文本表达式中的 TeX 方程式表达式。例如,要在标题中写出表达式 \(\sigma_i=15\),您可以写一个用美元符号包围的 TeX 表达式

plt.title(r'$\sigma_i=15$')

标题字符串之前的 r 很重要——它表示字符串是原始字符串,而不是将反斜杠视为 python 转义符。matplotlib 有一个内置的 TeX 表达式解析器和布局引擎,并附带自己的数学字体——有关详细信息,请参阅 编写数学表达式。因此,您可以在跨平台使用数学文本,而无需安装 TeX。对于那些安装了 LaTeX 和 dvipng 的用户,您也可以使用 LaTeX 来格式化您的文本并将输出直接合并到您的显示图形或保存的 PostScript 中——请参阅 使用 LaTeX 进行文本渲染

注释文本#

上述基本 text 函数的用法是在 Axes 上的任意位置放置文本。文本的常见用途是对绘图的某些特征进行注释,而 annotate 方法提供了辅助功能,使注释变得容易。在注释中,需要考虑两个点:由参数 xy 表示的被注释的位置和文本的位置 xytext。这两个参数都是 (x, y) 元组。

ax = plt.subplot()

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()
pyplot

在这个基本示例中,xy(箭头尖端)和 xytext 位置(文本位置)都在数据坐标系中。还有其他几种坐标系可供选择 - 有关详细信息,请参见 基本注释高级注释。更多示例可以在 注释绘图 中找到。

对数轴和其他非线性轴#

matplotlib.pyplot 不仅支持线性轴刻度,还支持对数刻度和 logit 刻度。这在数据跨越多个数量级时很常见。更改轴的刻度很容易

plt.xscale('log')

下面显示了四个具有相同数据但 y 轴刻度不同的绘图示例。

# Fixing random state for reproducibility
np.random.seed(19680801)

# make up some data in the open interval (0, 1)
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))

# plot with various axes scales
plt.figure()

# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)

# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)

# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthresh=0.01)
plt.title('symlog')
plt.grid(True)

# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# Adjust the subplot layout, because the logit one may take more space
# than usual, due to y-tick labels like "1 - 10^{-3}"
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
                    wspace=0.35)

plt.show()
linear, log, symlog, logit

也可以添加自己的刻度,有关详细信息,请参见 matplotlib.scale

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

由 Sphinx-Gallery 生成的图库