pythonic生物人

时隔2年,matplotlib迎来v3.11版本更新!

matplotlib是最常用的Python可视化工具,你几乎可以使用matplotlib绘制任何图表。

2026年6月11日,matplotlib迎来v3.11版本更新,距离上个版本接近2年。

Image

本文详解个人感觉有用的更新内容,详细参考官网。


新增Colormap.with_alpha方法

Colormap.with_alpha可在不改变颜色值的前提下,为整个colormap统一设置新的透明度(alpha)。该方法特别适合仅需调整Artist映射颜色透明度的场景,无需重建或修改原colormap。


新增复杂文本渲染方法

新增基于libraqm的复杂文本布局渲染方法:

  • 支持阿拉伯语、希伯来语等需要高级排版的语言
  • 支持从左到右与从右到左语言的自然混排
Image
  • 支持连字(ligature)渲染,可将多个相邻字符智能组合为单一字形,以提升可读性与排版美感。
Image
  • 支持多重变音符号或双倍宽度变音符号的组合排版。
Image

注意,所有高级排版功能均需字体本身提供支持,可能需要在内置DejaVu Sans之外另行安装其他字体。


新增OpenType字体特性标签支持

可通过fontfeatures参数精细控制连字等高级排版特性,配合libraqm实现复杂的多语言文本渲染,可通过以下方式控制:

  • matplotlib.text.Text.set_fontfeatures、matplotlib.text.Text.get_fontfeatures
  • 构造时直接传入,任何创建Text对象的API均支持fontfeatures参数,例如 plt.xlabel(..., fontfeatures=...)

例如,默认字体DejaVu Sans已开启标准连字(liga标签),同时提供可选的自由连字(dlig标签),可通过 +/ -切换开关。

fig = plt.figure(figsize=(7, 3))

fig.text(0.5, 0.85, 'Ligatures', fontsize=40, horizontalalignment='center')

# Default has Standard Ligatures (liga).
fig.text(0, 0.6, 'Default: fi ffi fl st', fontsize=40)

# Disable Standard Ligatures with -liga.
fig.text(0, 0.35, 'Disabled: fi ffi fl st', fontsize=40,
         fontfeatures=['-liga'])

# Enable Discretionary Ligatures with dlig.
fig.text(0, 0.1, 'Discretionary: fi ffi fl st', fontsize=40,
         fontfeatures=['dlig'])
Image

新增文本语种设置支持

可通过language参数指定BCP47语言代码,让OpenType字体根据语种自动选用本地化字形与排版规则。

例如,西里尔字母下的塞尔维亚语/马其顿语 vs 俄语,拉丁字母下的萨米语 vs 英语

fig = plt.figure(figsize=(7, 3))

char = 'U00000431'
fig.text(0.5, 0.8, f'\U{ord(char):08x}', fontsize=40, horizontalalignment='center')
fig.text(0, 0.6, f'Serbian: {char}', fontsize=40, language='sr') # language设置语种
fig.text(1, 0.6, f'Russian: {char}', fontsize=40, language='ru',
         horizontalalignment='right')

char = 'U0000014a'
fig.text(0.5, 0.3, f'\U{ord(char):08x}', fontsize=40, horizontalalignment='center')
fig.text(0, 0.1, f'Inari Sámi: {char}', fontsize=40, language='smn') # language设置语种
fig.text(1, 0.1, f'English: {char}', fontsize=40, language='en',
         horizontalalignment='right')
Image

Mathtext可区分italic和normal font

默认使用正体(mathnormal,数字直立),可通过 mathit显式指定斜体(数字倾斜),解决了此前无法排版斜体数字的问题。


Mathtext支持 \phantom, \llap, \rlap

  • phantom预留文本占位空间但不实际渲染
  • llap和rlap则在渲染文本的同时声明其不占空间
  • 三者结合可实现更精细的文本对齐控制

例如在图例中,可利用这些宏为短文本预留与长文本相同的空间,确保布局一致。

fig = plt.figure(layout="constrained")
sfs = fig.subfigures(2)

ax0 = sfs[0].add_subplot()
ax0.plot([1, 2], label=r"$\rlap{\text{foo}}\phantom{\text{a longer label}}$")
sfs[0].legend(loc="outside right upper")

ax1 = sfs[1].add_subplot()
ax1.plot([1, 2], label="foo")
ax1.plot([2, 1], label="a longer label")
sfs[1].legend(loc="outside right upper")
Image

Mathtext新增下划线支持

Mathtext新增对underline命令的支持,可在数学文本中直接为公式内容添加下划线。

plt.figure(figsize=(6, 2))
plt.text(0.05, 0.7, r'This is $\underline{underlined}$ text.', fontsize=24)
plt.text(0.05, 0.2, r'So is $\underline{\mathrm{this}}$.', fontsize=24)
plt.axis('off')
Image

改进了PDF输出中的字体嵌入机制

  • Type 3与 Type 42字体已无限制地嵌入PDF,超出格式限制的字体会被拆分为多个子集分别嵌入,并为每个子集添加正确的Unicode映射,确保所有文本在支持该功能的PDF查看器中均可正常选中和复制。

  • usetex模式下的 Type 1字体由原先全量嵌入改为仅嵌入图中实际使用到的字形,显著减小了输出 PDF 文件的体积。

Image

主次网格线引入了独立的样式控制

rcParams["grid.major.*"]和rcParams["grid.minor.*"]可分别设置主/次网格线的属性,并会覆盖通用的rcParams["grid.*"]配置。

import matplotlib as mpl

# 设置主网格线和次网格线是否可见
mpl.rcParams["axes.grid"] = True
mpl.rcParams["ytick.minor.visible"] = True
mpl.rcParams["xtick.minor.visible"] = True
mpl.rcParams["axes.grid.which"] = "both"

# 使用grid.* 统一设置主次网格线的属性
mpl.rcParams["grid.color"] = "lightgrey"

# 分别为主次网格线覆盖部分样式设置
mpl.rcParams["grid.major.linewidth"] = 1.2
mpl.rcParams["grid.minor.color"] = "tab:blue"
mpl.rcParams["grid.minor.linestyle"] = ":"

plt.plot([0, 1], [0, 1])
Image

新增pyplot与独立Figure的动态绑定机制

独立构造的Figure可通过plt.figure(fig)注册到pyplot,支持统一显示与管理;关闭窗口后图形转为独立状态,仍可继续操作或重新挂载。该机制在底层降低了Figure与后端之间的强耦合,提升了图形对象生命周期管理的灵活性。

import matplotlib.pyplot as plt
from matplotlib.figure import Figure

# 创建一个独立的Figure对象(未注册到pyplot)
fig = Figure()
ax = fig.add_subplot()
ax.plot([1, 2, 3], [4, 5, 6])

# 将该独立Figure注册到pyplot管理
plt.figure(fig)

# 通过pyplot接口修改图形属性
plt.xlabel("x label")

# 显示图形窗口
plt.show()

# 通过GUI界面关闭图形窗口(此时Figure自动解除pyplot绑定)

# 窗口关闭后仍可对原Figure对象进行操作
fig.savefig("my_figure.png")
ax.set_ylabel("y label")

# 重新注册到pyplot并再次显示
plt.figure(fig)
plt.show()

新增图形尺寸单位支持

plt.figure(..., figsize=(6, 4))设置图形size时,支持指定单位了,例如,plt.figure(..., figsize=(600,400,"px")),支持的单位包括"in"、"cm"和"px"。


支持在创建Figure时部分指定figsize

plt.rcParams['figure.figsize'] = (14, 11)
fig = plt.figure(figsize=(None, 4))  # 图性size为 (14, 4)

新增grouped_bar(),简化分组条形图的绘制

grouped_bar()支持多种输入数据类型(数据集列表、字典、二维数组、pandas DataFrame),并可通过调节组内柱间距与组间距离,灵活控制布局与外观。

categories = ['A', 'B'] # group标签,A组、B组

# 数值
datasets = {
'dataset 0': [1, 11],
'dataset 1': [3, 13],
'dataset 2': [5, 15],
}

fig, ax = plt.subplots()
ax.grouped_bar(datasets, tick_labels=categories) #grouped_bar使用
ax.legend()
Image

增强stackplot样式定制能力

stackplot现支持为facecolor、edgecolor、linestyle和linewidth传入序列参数,行为方式与已有的hatch参数一致,可为堆叠区域中的每一块分别指定样式。

x = np.linspace(0, 10)
y1 = x + np.sin(x)
y2 = x + np.cos(x)

fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, facecolor=['tab:orange', 'tab:green'])
Image

streamplot新增num_arrows参数

允许在每条流线上绘制多个箭头,增强矢量场方向的可视化效果。

w = 3
Y, X = np.mgrid[-w:w:100j, -w:w:100j]
U = -1 - X**2 + Y
V = 1 + X - Y**2

fig, ax = plt.subplots()
ax.streamplot(X, Y, U, V, num_arrows=3) #每条流线上绘制3个箭头
Image

violinplot与violin新增facecolor和linecolor颜色参数

可在绘图时直接设置小提琴图的填充色与线条色,无需事后逐个修改对象。支持传入单一颜色应用于所有小提琴,也可传入颜色序列实现逐图着色。

np.random.seed(19680801)
data = [sorted(np.random.normal(0, std, 100)) for std in range(1, 5)]

fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, sharey=True)

ax1.set_title('Default violin plot')
ax1.set_ylabel('Observed values')
ax1.violinplot(data)

ax2.set_title('Set colors of violins')
ax2.set_ylabel('Observed values')
ax2.violinplot(
    data,
# facecolor使用
    facecolor=[('yellow', 0.3), ('blue', 0.3), ('red', 0.3), ('green', 0.3)],
# linecolor使用
    linecolor='black',
)
Image

bar_label支持为每个标签单独设置padding

padding参数现在既可接受单个浮点值(统一间距),也可接受类数组对象,为柱状图中的各个标签分别指定不同的边距。


pie图新增pie_label方法

pie_label方法为每个扇区添加标签,支持字符串列表、格式化字符串两种输入方法。

data = [36, 24, 8, 12]
labels = ['spam', 'eggs', 'bacon', 'sausage']

fig, ax = plt.subplots()
pie = ax.pie(data)

# pie_label使用
ax.pie_label(pie, labels, distance=1.1)
ax.pie_label(pie, '{frac:.1%}', distance=0.7)
ax.pie_label(pie, '{absval:d}', distance=0.4)
Image

新增xtick与ytick旋转模式

引入"xtick"和"ytick"两种新的旋转模式,可更直观地控制刻度标签旋转。该模式会自动调整旋转后标签的对齐方式,使文字指向其锚点(即刻度线本身),适用于图像四边(下、上、左、右)的刻度标签,大幅减少旋转标签时的手动微调工作。

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(7, 3.5), layout='constrained')

pos = range(5)
labels = ['label'] * 5
ax1.set_xticks(pos, labels, rotation=-45, rotation_mode='xtick')
ax1.set_yticks(pos, labels, rotation=45, rotation_mode='ytick')
ax2.xaxis.tick_top()
ax2.set_xticks(pos, labels, rotation=-45, rotation_mode='xtick')
ax2.yaxis.tick_right()
ax2.set_yticks(pos, labels, rotation=45, rotation_mode='ytick')
Image

新增Okabe-Ito无障碍colormap

该colormap专为色觉缺陷人群设计,其颜色在常见色盲类型及打印场景下仍保持良好区分度。

import matplotlib.pyplot as plt
from cycler import cycler

plt.rcParams['axes.prop_cycle'] = cycler(color='okabe_ito')
plt.rcParams['image.cmap'] = 'okabe_ito'
Image

新增6色与8色Petroff无障碍color cycles

命名为'petroff6'与'petroff8',是对Matplotlib 3.10.0已引入的'petroff10'的补充。如需加载'petroff6'以替代默认颜色循环,可使用

import matplotlib.pyplot as plt
plt.style.use('petroff6')
Image

支持matplotlibrc或style文件中将任意命名颜色序列设为默认颜色cycle

支持在matplotlibrc或style文件中将任意命名颜色序列设为默认颜色循环。例如:

axes.prop_cycle : cycler(color='Accent')

定义异常值与越界值的显示颜色

colormap构造函数现支持bad、under、over关键字参数,可在创建时一次性定义异常值与越界值的显示颜色。此前需通过set_bad、set_under、set_over、set_extremes或with_extremes等方法在创建后进行设置。推荐使用新接口,示例如下:

cmap = ListedColormap(colors, bad="red", under="darkblue", over="purple")

替代老方法,

cmap = ListedColormap(colors).with_extremes(
    bad="red", under="darkblue", over="purple")

# 或者

cmap = ListedColormap(colors)
cmap.set_bad("red")
cmap.set_under("darkblue")
cmap.set_over("purple")

关注公众号「pythonic生物人」,第一时间获取免AI、数据可视化、科研干货,下期见!


往期精彩

2026可视化工具TOP3

复现IF50.0期刊上6张图

复现Science正刊图

复现顶刊forestplot

师姐认为你会的55个科研图表

师弟师妹偷偷用的7大科研图表

复现Nature中的PCA图

复现Cell图