Matplotlib 3.6.0 (2022年9月15日) 更新内容#
有关自上次修订以来的所有问题和拉取请求列表,请参阅 GitHub 3.11.0 版本统计信息 (2026年6月11日)。
图形(Figure)和轴(Axes)的创建/管理#
subplots 和 subplot_mosaic 支持 height_ratios 和 width_ratios 参数#
现在可以通过向 subplots 和 subplot_mosaic 方法传递 height_ratios 和 width_ratios 关键字参数来控制行和列的相对宽高。
fig = plt.figure()
axs = fig.subplots(3, 1, sharex=True, height_ratios=[3, 1, 1])
此前,这需要通过 gridspec_kw 参数传递比例。
fig = plt.figure()
axs = fig.subplots(3, 1, sharex=True,
gridspec_kw=dict(height_ratios=[3, 1, 1]))
约束布局不再被视为实验性功能#
约束布局引擎和 API 不再被视为实验性。未经弃用期,不得对行为和 API 进行随意更改。
新的 layout_engine 模块#
Matplotlib 随附了 tight_layout 和 constrained_layout 布局引擎。新增了 layout_engine 模块,允许下游库编写自己的布局引擎。现在 Figure 对象可以将 LayoutEngine 的子类作为 layout 参数的参数。
针对固定长宽比 Axes 的压缩布局#
现在可以使用 fig, axs = plt.subplots(2, 3, layout='compressed') 将具有固定长宽比的简单 Axes 排列在一起。
使用 layout='tight' 或 'constrained' 时,具有固定长宽比的 Axes 之间可能会留下较大的空隙。
使用 layout='compressed' 布局可以减少 Axes 之间的空间,并将额外空间添加到外边距中。
更多详情请参阅 固定长宽比 Axes 的网格:"compressed" 布局。
布局引擎现在可以被移除#
现在可以通过调用带有 'none' 的 Figure.set_layout_engine 来移除 Figure 上的布局引擎。这在计算布局后为了减少计算量(例如,在后续动画循环中)可能很有用。
只要与之前的布局引擎兼容,之后可以设置不同的布局引擎。
Axes.inset_axes 的灵活性提升#
matplotlib.axes.Axes.inset_axes 现在接受 projection, polar 和 axes_class 关键字参数,以便可以返回 matplotlib.axes.Axes 的子类。
fig, ax = plt.subplots()
ax.plot([0, 2], [1, 2])
polar_ax = ax.inset_axes([0.75, 0.25, 0.2, 0.2], projection='polar')
polar_ax.plot([0, 2], [1, 2])
WebP 现已成为受支持的输出格式#
现在可以通过使用 .webp 文件扩展名或向 savefig 传递 format='webp' 来以 WebP 格式保存图形。这依赖于 Pillow 对 WebP 的支持。
关闭图形时不再自动运行垃圾回收#
Matplotlib 中存在大量循环引用(Figure 与 Manager 之间,Axes 与 Figure 之间,Axes 与 Artist 之间,Figure 与 Canvas 之间等),因此当用户丢弃对 Figure 的最后一个引用(并从 pyplot 的状态中清除它)时,这些对象不会立即被删除。
为了解决这个问题,我们在关闭代码中长期(自 2004 年之前)运行 gc.collect(仅最低两代),以便及时清理。然而,这不仅没有达到我们想要的效果(因为我们的大多数对象实际上会存活),而且由于清除了第一代,导致了无限制的内存使用。
在创建图形和销毁图形之间循环非常紧密的情况下(例如 plt.figure(); plt.close()),第一代永远不会增长到足够大,以至于 Python 考虑在更高代上运行垃圾回收。这将导致无限制的内存使用,因为长生命周期对象永远不会被重新考虑以寻找引用循环,因此永远不会被删除。
我们现在在关闭图形时不再进行任何垃圾回收,而是依赖 Python 定期自动决定运行垃圾回收。如果您有严格的内存要求,您可以自行调用 gc.collect,但这可能会在紧密计算循环中产生性能影响。
绘图方法#
条纹线(实验性)#
plot 的新 gapcolor 参数可以创建条纹线。
x = np.linspace(1., 3., 10)
y = x**3
fig, ax = plt.subplots()
ax.plot(x, y, linestyle='--', color='orange', gapcolor='blue',
linewidth=3, label='a striped line')
ax.legend()
bxp 和 boxplot 中箱线图的自定义上限宽度#
bxp 和 boxplot 的新 capwidths 参数允许控制箱线图中上限(caps)的宽度。
x = np.linspace(-7, 7, 140)
x = np.hstack([-25, x, 25])
capwidths = [0.01, 0.2]
fig, ax = plt.subplots()
ax.boxplot([x, x], notch=True, capwidths=capwidths)
ax.set_title(f'{capwidths=}')
条形图的条形标注更简便#
现在可以将标签列表传递给 bar 和 barh 的 label 参数。该列表必须与 x 的长度相同,并标注各个条形。重复的标签不会被去重,并会导致重复的标签条目,因此最好在条形图的样式也不同时使用(例如,通过将列表传递给 color,如下所示)。
x = ["a", "b", "c"]
y = [10, 20, 15]
color = ['C0', 'C1', 'C2']
fig, ax = plt.subplots()
ax.bar(x, y, color=color, label=x)
ax.legend()
颜色条刻度的新样式格式字符串#
colorbar(以及其他颜色条方法)的 format 参数现在接受 {} 风格的格式字符串。
fig, ax = plt.subplots()
im = ax.imshow(z)
fig.colorbar(im, format='{x:.2e}') # Instead of '%.2e'
负值等高线的线型可以单独设置#
通过将 negative_linestyles 参数传递给 Axes.contour,可以设置负值等高线的线型。此前,该样式只能通过 rcParams["contour.negative_linestyle"](默认值:'dashed')进行全局设置。
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
fig, axs = plt.subplots(1, 2)
CS = axs[0].contour(X, Y, Z, 6, colors='k')
axs[0].clabel(CS, fontsize=9, inline=True)
axs[0].set_title('Default negative contours')
CS = axs[1].contour(X, Y, Z, 6, colors='k', negative_linestyles='dotted')
axs[1].clabel(CS, fontsize=9, inline=True)
axs[1].set_title('Dotted negative contours')
通过 ContourPy 改进四边形等高线计算#
等高线函数 contour 和 contourf 有一个新的关键字参数 algorithm,用于控制计算等高线所使用的算法。有四种算法可供选择,默认使用 algorithm='mpl2014',这与 Matplotlib 自 2014 年以来一直使用的算法相同。
此前 Matplotlib 附带了自己用于计算四边形网格等高线的 C++ 代码。现在改为使用外部库 ContourPy。
目前 algorithm 关键字参数的其他可能值为 'mpl2005', 'serial' 和 'threaded';更多详情请参阅 ContourPy 文档。
注意
由 algorithm='mpl2014' 产生的等高线和多边形与此更改之前产生的结果在浮点数误差范围内相同。例外情况是重复点,即包含相同相邻 (x, y) 点的等高线;此前重复点会被移除,现在则被保留。受此影响的等高线将产生相同的视觉输出,但在等高线中会有更多的点。
使用 clabel 获得的等高线标签的位置也可能有所不同。
errorbar 支持 markerfacecoloralt#
现在 markerfacecoloralt 参数从 Axes.errorbar 传递给线绘图器。文档现在准确列出了哪些属性被传递给 Line2D,而不是声称所有关键字参数都会被传递。
x = np.arange(0.1, 4, 0.5)
y = np.exp(-x)
fig, ax = plt.subplots()
ax.errorbar(x, y, xerr=0.2, yerr=0.4,
linestyle=':', color='darkgrey',
marker='o', markersize=20, fillstyle='left',
markerfacecolor='tab:blue', markerfacecoloralt='tab:orange',
markeredgecolor='tab:brown', markeredgewidth=2)
streamplot 可以禁用流线断开#
现在可以指定流线图具有连续、不间断的流线。此前,流线会为了限制单个网格单元内的线条数量而结束。请看下方绘图之间的区别
新的轴尺度 asinh(实验性)#
新的 asinh 轴尺度提供了 symlog 的替代方案,可以在尺度的准线性区域和渐进对数区域之间平滑过渡。这是基于 arcsinh 转换的,允许绘制跨越多个数量级的正值和负值。
stairs(..., fill=True) 通过设置线宽隐藏补丁边缘#
stairs(..., fill=True) 此前通过设置 edgecolor="none" 来隐藏补丁边缘。因此,稍后在补丁上调用 set_color() 会使补丁看起来更大。
现在,通过使用 linewidth=0,可以防止这种明显的尺寸变化。同样,调用 stairs(..., fill=True, linewidth=3) 的表现也会更加透明。
修复 Patch 类的虚线偏移#
以前,在使用虚线元组在 Patch 对象上设置线型时,偏移量会被忽略。现在,偏移量会按预期应用于 Patch,并且可以像在 Line2D 对象上那样使用它。
矩形补丁旋转点#
现在可以使用 rotation_point 参数将 Rectangle 的旋转点设置为 'xy', 'center' 或数字二元组。
颜色和颜色映射#
颜色序列注册表#
颜色序列注册表 ColorSequenceRegistry 包含了 Matplotlib 按名称识别的颜色序列(即简单的列表)。通常不会直接使用它,而是通过 matplotlib.color_sequences 的通用实例来使用。
用于创建不同查找表大小的 Colormap 方法#
新的方法 Colormap.resampled 创建了一个具有指定查找表大小的新 Colormap 实例。这是通过 get_cmap 操作查找表大小的替代方案。
使用
get_cmap(name).resampled(N)
代替
get_cmap(name, lut=N)
使用字符串设置规范(norms)#
现在可以使用对应尺度的字符串名称来设置规范(例如在图像上),例如 imshow(array, norm="log")。请注意,在这种情况下,允许传递 vmin 和 vmax,因为底层会自动创建一个新的 Norm 实例。
标题、刻度和标签#
plt.xticks 和 plt.yticks 支持 minor 关键字参数#
现在可以通过设置 minor=True 使用 pyplot.xticks 和 pyplot.yticks 来设置或获取次刻度。
plt.figure()
plt.plot([1, 2, 3, 3.5], [2, 1, 0, -0.5])
plt.xticks([1, 2, 3], ["One", "Zwei", "Trois"])
plt.xticks([np.sqrt(2), 2.5, np.pi],
[r"$\sqrt{2}$", r"$\frac{5}{2}$", r"$\pi$"], minor=True)
图例#
图例可以控制标题和句柄的对齐#
Legend 现在支持通过关键字参数 alignment 控制标题和句柄的对齐。您也可以使用 Legend.set_alignment 来控制现有图例的对齐方式。
fig, axs = plt.subplots(3, 1)
for i, alignment in enumerate(['left', 'center', 'right']):
axs[i].plot(range(10), label='test')
axs[i].legend(title=f'{alignment=}', alignment=alignment)
legend 的 ncol 关键字参数重命名为 ncols#
用于控制列数的 legend 的 ncol 关键字参数已重命名为 ncols,以便与 subplots 和 GridSpec 的 ncols 和 nrows 关键字保持一致。ncol 仍然受支持以实现向后兼容,但不推荐使用。
标记(Markers)#
marker 现在可以设置为字符串 "none"#
字符串 "none" 表示 no-marker,这与其他支持小写版本的 API 一致。推荐使用 "none" 而不是 "None",以避免与 None 对象混淆。
MarkerStyle 的连接样式和上限样式自定义#
新的 MarkerStyle 参数允许控制连接样式和上限样式,并允许用户提供要应用于标记的转换(例如旋转)。
from matplotlib.markers import CapStyle, JoinStyle, MarkerStyle
from matplotlib.transforms import Affine2D
fig, axs = plt.subplots(3, 1, layout='constrained')
for ax in axs:
ax.axis('off')
ax.set_xlim(-0.5, 2.5)
axs[0].set_title('Cap styles', fontsize=14)
for col, cap in enumerate(CapStyle):
axs[0].plot(col, 0, markersize=32, markeredgewidth=8,
marker=MarkerStyle('1', capstyle=cap))
# Show the marker edge for comparison with the cap.
axs[0].plot(col, 0, markersize=32, markeredgewidth=1,
markerfacecolor='none', markeredgecolor='lightgrey',
marker=MarkerStyle('1'))
axs[0].annotate(cap.name, (col, 0),
xytext=(20, -5), textcoords='offset points')
axs[1].set_title('Join styles', fontsize=14)
for col, join in enumerate(JoinStyle):
axs[1].plot(col, 0, markersize=32, markeredgewidth=8,
marker=MarkerStyle('*', joinstyle=join))
# Show the marker edge for comparison with the join.
axs[1].plot(col, 0, markersize=32, markeredgewidth=1,
markerfacecolor='none', markeredgecolor='lightgrey',
marker=MarkerStyle('*'))
axs[1].annotate(join.name, (col, 0),
xytext=(20, -5), textcoords='offset points')
axs[2].set_title('Arbitrary transforms', fontsize=14)
for col, (size, rot) in enumerate(zip([2, 5, 7], [0, 45, 90])):
t = Affine2D().rotate_deg(rot).scale(size)
axs[2].plot(col, 0, marker=MarkerStyle('*', transform=t))
字体和文本#
字体回退#
现在可以指定字体族列表,Matplotlib 将依次尝试它们以找到所需的字形。
plt.rcParams["font.size"] = 20
fig = plt.figure(figsize=(4.75, 1.85))
text = "There are 几个汉字 in between!"
fig.text(0.05, 0.65, text, family=["Noto Sans CJK JP", "Noto Sans TC"])
fig.text(0.05, 0.45, text, family=["DejaVu Sans", "Noto Sans CJK JP", "Noto Sans TC"])
带有字体回退的英语和中文混合文本演示。
目前这适用于 Agg(以及所有的 GUI 嵌入)、svg、pdf、ps 和 inline 后端。
可用字体名称列表#
现在可以轻松访问可用字体列表。要获取 Matplotlib 中可用字体名称的列表,请使用
from matplotlib import font_manager
font_manager.get_font_names()
math_to_image 现在有 color 关键字参数#
为了轻松支持依赖 Matplotlib 的 MathText 渲染来生成方程式图像的外部库,向 math_to_image 添加了 color 关键字参数。
from matplotlib import mathtext
mathtext.math_to_image('$x^2$', 'filename.png', color='Maroon')
活动 URL 区域随链接文本旋转#
当链接文本在图形中旋转时,活动 URL 区域现在将包括旋转后的链接区域。此前,活动区域保持在原始的、未旋转的位置。
rcParams 改进#
允许全局设置图形标签大小和粗细,并与标题区分开#
对于图形标签 Figure.supxlabel 和 Figure.supylabel,现在可以使用 rcParams["figure.labelsize"](默认值:'large')和 rcParams["figure.labelweight"](默认值:'normal')单独设置大小和粗细,与图形标题区分开。
# Original (previously combined with below) rcParams:
plt.rcParams['figure.titlesize'] = 64
plt.rcParams['figure.titleweight'] = 'bold'
# New rcParams:
plt.rcParams['figure.labelsize'] = 32
plt.rcParams['figure.labelweight'] = 'bold'
fig, axs = plt.subplots(2, 2, layout='constrained')
for ax in axs.flat:
ax.set(xlabel='xlabel', ylabel='ylabel')
fig.suptitle('suptitle')
fig.supxlabel('supxlabel')
fig.supylabel('supylabel')
请注意,如果您更改了 rcParams["figure.titlesize"](默认值:'large')或 rcParams["figure.titleweight"](默认值:'normal'),现在必须同时更改引入的这些参数,以获得与过去行为一致的结果。
可以全局禁用 Mathtext 解析#
设置 rcParams["text.parse_math"](默认值:True)可用于禁用所有 Text 对象中的 mathtext 解析(最显著的是来自 Axes.text 方法)。
matplotlibrc 中的双引号字符串#
现在可以在字符串周围使用双引号。这允许在字符串中使用 '#' 字符。如果没有引号,'#' 会被解释为注释的开始。特别地,您现在可以定义十六进制颜色
grid.color: "#b0b0b0"
3D Axes 改进#
主要平面观察角度的标准化视图#
在主要视图平面(即垂直于 XY、XZ 或 YZ 平面)查看 3D 绘图时,轴将显示在标准位置。有关 3D 视图的更多信息,请参阅 mplot3d 观察角度 和 3D 主要观察平面。
3D 相机的自定义焦距#
通过指定虚拟相机的焦距,3D Axes 现在可以更好地模拟现实世界的相机。默认焦距 1 对应 90° 的视野(FOV),并与现有的 3D 绘图向后兼容。焦距在 1 到无穷大之间增加会使图像“变平”,而焦距在 1 到 0 之间减少会夸大透视并赋予图像更明显的深度感。
焦距可以通过所需 FOV 的等式计算

from mpl_toolkits.mplot3d import axes3d
X, Y, Z = axes3d.get_test_data(0.05)
fig, axs = plt.subplots(1, 3, figsize=(7, 4),
subplot_kw={'projection': '3d'})
for ax, focal_length in zip(axs, [0.2, 1, np.inf]):
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
ax.set_proj_type('persp', focal_length=focal_length)
ax.set_title(f"{focal_length=}")
3D 绘图增加了第 3 个“滚动(roll)”观察角度#
通过增加第 3 个滚动角度,现在可以从任何方向查看 3D 绘图,该角度绕观察轴旋转绘图。使用鼠标进行交互式旋转仍然只控制仰角和方位角,这意味着此功能适用于以编程方式创建更复杂相机角度的用户。默认的滚动角度为 0,与现有的 3D 绘图向后兼容。
from mpl_toolkits.mplot3d import axes3d
X, Y, Z = axes3d.get_test_data(0.05)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
ax.view_init(elev=0, azim=0, roll=30)
ax.set_title('elev=0, azim=0, roll=30')
3D 绘图的等比例#
用户可以将 3D 绘图的 X、Y、Z 轴长宽比设置为 'equal', 'equalxy', 'equalxz' 或 'equalyz',而不是默认的 'auto'。
from itertools import combinations, product
aspects = [
['auto', 'equal', '.'],
['equalxy', 'equalyz', 'equalxz'],
]
fig, axs = plt.subplot_mosaic(aspects, figsize=(7, 6),
subplot_kw={'projection': '3d'})
# Draw rectangular cuboid with side lengths [1, 1, 5]
r = [0, 1]
scale = np.array([1, 1, 5])
pts = combinations(np.array(list(product(r, r, r))), 2)
for start, end in pts:
if np.sum(np.abs(start - end)) == r[1] - r[0]:
for ax in axs.values():
ax.plot3D(*zip(start*scale, end*scale), color='C0')
# Set the aspect ratios
for aspect, ax in axs.items():
ax.set_box_aspect((3, 4, 5))
ax.set_aspect(aspect)
ax.set_title(f'set_aspect({aspect!r})')
交互式工具改进#
旋转、长宽比校正和状态添加/移除#
RectangleSelector 和 EllipseSelector 现在可以在 -45° 到 45° 之间交互式旋转。范围限制目前由实现决定。旋转通过按下 r 键('r' 是 state_modifier_keys 中映射到 'rotate' 的默认键)或调用 selector.add_state('rotate') 来启用或禁用。
使用“正方形”状态时,现在可以将轴的长宽比考虑在内。通过在初始化选择器时指定 use_data_coordinates='True' 来启用此功能。
除了使用 state_modifier_keys 中定义的修饰键交互式更改选择器状态外,现在还可以使用 add_state 和 remove_state 方法以编程方式更改选择器状态。
from matplotlib.widgets import RectangleSelector
values = np.arange(0, 100)
fig = plt.figure()
ax = fig.add_subplot()
ax.plot(values, values)
selector = RectangleSelector(ax, print, interactive=True,
drag_from_anywhere=True,
use_data_coordinates=True)
selector.add_state('rotate') # alternatively press 'r' key
# rotate the selector interactively
selector.remove_state('rotate') # alternatively press 'r' key
selector.add_state('square')
MultiCursor 现在支持跨多个图形分割的 Axes#
此前,MultiCursor 仅在所有目标 Axes 属于同一个图形时才有效。
由于这一更改,MultiCursor 构造函数的第一个参数不再使用(它以前是所有 Axes 的联合画布,但现在可以从 Axes 列表中直接推断出画布)。
PolygonSelector 边界框#
PolygonSelector 现在有一个 draw_bounding_box 参数,设置为 True 时,多边形完成后会在其周围绘制一个边界框。边界框可以调整大小和移动,从而轻松调整多边形的点。
设置 PolygonSelector 顶点#
现在可以使用 PolygonSelector.verts 属性以编程方式设置 PolygonSelector 的顶点。以这种方式设置顶点将重置选择器,并使用提供的顶点创建一个新的完整选择器。
SpanSelector 小部件现在可以吸附到指定值#
SpanSelector 小部件现在可以吸附到由 snap_values 参数指定的值。
更多的工具栏图标适配了深色主题#
在 macOS 和 Tk 后端上,使用深色主题时工具栏图标现在将被反转。
特定平台更改#
Wx 后端使用标准工具栏#
在 Wx 窗口上,工具栏被设置为标准工具栏,而不是自定义的 sizer。
macosx 后端改进#
修饰键处理更一致#
macosx 后端现在以与其他后端更一致的方式处理修饰键。更多信息请参阅 事件连接 中的表格。
savefig.directory rcParam 支持#
macosx 后端现在将遵守 rcParams["savefig.directory"](默认值:'~')设置。如果设置为非空字符串,保存对话框将默认为此目录,并在后续保存目录更改时保留这些目录。
figure.raise_window rcParam 支持#
macosx 后端现在将遵守 rcParams["figure.raise_window"](默认值:True)设置。如果设置为 False,图形窗口在更新时将不会被置顶。
全屏切换支持#
与其他后端一样,macosx 后端现在支持切换全屏视图。默认情况下,可以通过按下 f 键来切换此视图。
改进了动画和 blitting 支持#
macosx 后端已得到改进,修复了 blitting 和带有新艺术家的动画帧,并减少了不必要的绘图调用。
macOS 应用程序图标应用于 Qt 后端#
在 macOS 上使用基于 Qt 的后端时,应用程序图标现在将被设置,就像在其他后端/平台上所做的那样。
新的 macOS 最低版本要求#
macosx 后端现在需要 macOS >= 10.12。
Windows on ARM 支持#
已添加对 Windows on arm64 目标的初步支持。此支持需要 FreeType 2.11 或更高版本。
目前尚无二进制 wheel,但可以从源代码构建。