Matplotlib 全面使用指南 -- 自动缩放坐标轴 Autoscaling Axis
文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。
自动缩放坐标轴
坐标轴的范围可以手动设置(例如使用 ax.set_xlim(xmin, xmax)
),或者由 Matplotlib 根据坐标轴上已有的数据自动设置。自动缩放行为有多种选项,下面将对此进行讨论。
我们将从一个简单的折线图开始,展示自动缩放如何将坐标轴范围扩展到数据范围(-2π, 2π)之外 5%。
import matplotlib.pyplot as plt
import numpy as npimport matplotlib as mplx = np.linspace(-2 * np.pi, 2 * np.pi, 100)
y = np.sinc(x)fig, ax = plt.subplots()
ax.plot(x, y)
边距(Margins)
数据范围周围的默认边距为 5%,这是基于默认配置设置 rcParams["axes.xmargin"]
(默认值:0.05
)、rcParams["axes.ymargin"]
(默认值:0.05
)和 rcParams["axes.zmargin"]
(默认值:0.05
):
print(ax.margins())
输出:
(0.05, 0.05)
可以使用 margins
方法覆盖边距大小,使其变小或变大:
fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(0.2, 0.2)
通常,边距的范围可以是 (-0.5, ∞),其中负边距会将坐标轴范围设置为数据范围的子范围,即裁剪数据。使用单个数字会影响两个坐标轴,可以使用关键字参数 x
或 y
自定义单个边距,但不能同时使用位置参数和关键字参数。
fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(y=-0.2)
粘性边缘(Sticky edges)
有些绘图元素(Artist
)通常不使用边距。例如,伪彩色图像(例如使用 Axes.imshow
创建的图像)不参与边距计算。
xx, yy = np.meshgrid(x, x)
zz = np.sinc(np.sqrt((xx - 1)**2 + (yy - 1)**2))fig, ax = plt.subplots(ncols=2, figsize=(12, 8))
ax[0].imshow(zz)
ax[0].set_title("default margins")
ax[1].imshow(zz)
ax[1].margins(0.2)
ax[1].set_title("margins(0.2)")
这种边距的覆盖由“粘性边缘”决定,这是 Artist
类的一个属性,可以抑制将边距添加到坐标轴范围。粘性边缘的效果可以通过更改 use_sticky_edges
在坐标轴上禁用。Artist
具有 Artist.sticky_edges
属性,粘性边缘的值可以通过写入 Artist.sticky_edges.x
或 Artist.sticky_edges.y
来更改。
以下示例展示了覆盖的工作原理以及何时需要它。
fig, ax = plt.subplots(ncols=3, figsize=(16, 10))
ax[0].imshow(zz)
ax[0].margins(0.2)
ax[0].set_title("default use_sticky_edges\nmargins(0.2)")
ax[1].imshow(zz)
ax[1].margins(0.2)
ax[1].use_sticky_edges = False
ax[1].set_title("use_sticky_edges=False\nmargins(0.2)")
ax[2].imshow(zz)
ax[2].margins(-0.2)
ax[2].set_title("default use_sticky_edges\nmargins(-0.2)")
我们可以看到,将 use_sticky_edges
设置为 False 会使用请求的边距渲染图像。
虽然粘性边缘不会通过额外边距增加坐标轴范围,但负边距仍然会被考虑。这可以在第三张图像的缩小范围中看到。
控制自动缩放(Controlling autoscale)
默认情况下,每次向绘图添加新曲线时都会重新计算范围:
fig, ax = plt.subplots(ncols=2, figsize=(12, 8))
ax[0].plot(x, y)
ax[0].set_title("Single curve")
ax[1].plot(x, y)
ax[1].plot(x * 2.0, y)
ax[1].set_title("Two curves")
但是,在某些情况下,您可能不希望自动调整视口以适应新数据。
禁用自动缩放的一种方法是手动设置坐标轴范围。假设我们想更详细地查看数据的一部分。设置 xlim
后,即使向数据中添加更多曲线,该设置也会保持不变。要重新计算新范围,调用 Axes.autoscale
将手动切换该功能。
fig, ax = plt.subplots(ncols=2, figsize=(12, 8))
ax[0].plot(x, y)
ax[0].set_xlim(left=-1, right=1)
ax[0].plot(x + np.pi * 0.5, y)
ax[0].set_title("set_xlim(left=-1, right=1)\n")
ax[1].plot(x, y)
ax[1].set_xlim(left=-1, right=1)
ax[1].plot(x + np.pi * 0.5, y)
ax[1].autoscale()
ax[1].set_title("set_xlim(left=-1, right=1)\nautoscale()")
我们可以使用 Axes.get_autoscale_on()
检查第一个绘图是否禁用了自动缩放,以及第二个绘图是否重新启用了它:
print(ax[0].get_autoscale_on()) # False 表示已禁用
print(ax[1].get_autoscale_on()) # True 表示已启用 -> 重新计算
输出:
False
True
autoscale
函数的参数让我们可以精确控制自动缩放过程。参数 enable
和 axis
的组合可以为选定的坐标轴(或两个坐标轴)设置自动缩放功能。参数 tight
将选定坐标轴的边距设置为零。要保留 enable
或 tight
的设置,可以将另一个设置为 None,这样它就不会被修改。但是,将 enable
设置为 None 并将 tight
设置为 True 会影响两个坐标轴,而不管 axis
参数如何。
处理集合(Working with collections)
自动缩放适用于添加到坐标轴的所有线条、填充和图像。它不适用的艺术家之一是 Collection
。将集合添加到坐标轴后,必须手动触发 autoscale_view()
以重新计算坐标轴范围。
fig, ax = plt.subplots()
collection = mpl.collections.StarPolygonCollection(5, rotation=0, sizes=(250,), # 五角星,零角度,大小 250 像素offsets=np.column_stack([x, y]), # 设置位置offset_transform=ax.transData, # 传播坐标轴的变换
)
ax.add_collection(collection)
ax.autoscale_view()
输出:
(0, 0)
处理集合
自动缩放功能对添加到坐标轴的所有线条、填充和图像都能直接生效。然而,对于 Collection
类型的艺术家对象,自动缩放不会自动工作。将集合添加到坐标轴后,必须手动触发 autoscale_view()
来重新计算坐标轴范围。
fig, ax = plt.subplots()
collection = mpl.collections.StarPolygonCollection(5, rotation=0, sizes=(250,), # five point star, zero angle, size 250pxoffsets=np.column_stack([x, y]), # Set the positionsoffset_transform=ax.transData, # Propagate transformations of the Axes
)
ax.add_collection(collection)
ax.autoscale_view()
Download Jupyter notebook: autoscale.ipynb
Download Python source code: autoscale.py
Download zipped: autoscale.zip
风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。