0 自动放缩
轴上的限制可以手动设置(例如ax.set_xlim(xmin, xmax)),或者Matplotlib可以根据Axes上已有的数据自动设置它们。此种放缩行为有许多选项,如下所述。
我们将从一个简单的折线图开始,显示自动缩放将轴限制扩展到数据的极限 ( − 2 π , 2 π ) (-2\pi, 2\pi) (−2π,2π)之外5%。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
x = np.linspace(-2 * np.pi, 2 * np.pi, 100)
y = np.sinc(x)
fig, ax = plt.subplots()
ax.plot(x, y)
小白按:matplotlib的默认自动放缩就是以数据分布极限的±5%的余量来控制绘图的。下面将会讲到“余量”(裕度),默认余量等概念。
1 边距裕度
默认的边距裕度为数据极限的5%,这是基于rcParams["axes.xmargin"]
(默认0.5)、rcParams["axes.ymargin"]
(默认0.5)和rcParams["axes.zmargin"]
(默认0.5)的默认配置设置:
print(ax.margins())
输出为:
(0.05, 0.05)
可以修改裕度参数来让边距更小或更大:
fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(0.2, 0.2)
通常,边距裕度可以在(-0.5, ∞)范围内,其中负边距将axes限制设置为数据范围的子范围,即它们的裁剪数据。使用单个数字作为边距裕度会影响两个轴,可以使用关键字参数x或y自定义单个边距,但位置和关键字接口不能同时组合。
fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(y=-0.2)
2 粘性边缘
有些绘图元素(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
会呈现具有请求边距的图像。
虽然粘性边界不会通过额外的边距裕度来增加轴限制,但仍会考虑负边距(即使没有将use_sticky_edges
设置为False
)。这可以从第三张图像的减小限制中看出。
3 控制自动缩放
默认情况下,每次向绘图添加新曲线时,都会重新计算极限:
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 means disabled
print(ax[1].get_autoscale_on()) # True means enabled -> recalculated
输出:
False
True
自动缩放函数的参数为我们提供了对自动缩放过程的精确控制。参数enable
和axis
的组合设置所选轴(或两者)的自动缩放功能。参数tight
将所选轴的边距裕度设置为零。要保留enable
或tight
的设置,你可以将相对的参数设置为None
,这样就不应该修改它。但是,将enable
设置为None
和tight
设置为True
会影响两个轴,而不考虑轴参数。
fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(0.2, 0.2)
ax.autoscale(enable=None, axis="x", tight=True)
print(ax.margins())
输出为
(0,0)
4 使用Collection
自动缩放功能开箱即用,适用于添加到Axes的所有线条、面片和图像。它不会与之合作的Artist类之一是Collection。将集合添加到Axes后,必须手动触发autoscale_view()
以重新计算轴限制。
fig, ax = plt.subplots()
collection = mpl.collections.StarPolygonCollection(
5, rotation=0, sizes=(250,), # five point star, zero angle, size 250px
offsets=np.column_stack([x, y]), # Set the positions
offset_transform=ax.transData, # Propagate transformations of the Axes
)
ax.add_collection(collection)
ax.autoscale_view()