matplotlib 子图:如何冻结 x 轴和 y 轴?

matplotlib subplots: how to freeze x and y axis?

晚上好

matplotlib 在使用例如绘图时更改图表的缩放比例hist()plot(),这通常很棒。

是否可以在绘制后冻结子图中的 x 和 y 轴,以便进一步的绘制命令不再更改它们?例如:

fig, (plt1, plt2) = plt.subplots(2, 1, figsize=(20, 10))
plt1.hist(…)
plt1.plot(…)

# How can this get done?:
plt1.Freeze X- and Y-Axis

# Those commands no longer changes the x- and y-axis
plt1.plot(…)
plt1.plot(…)

非常感谢,亲切的问候, 托马斯

要冻结x-axis在绘图函数上指定域:

import matplotlib.pyplot as plt

fig, (plt1, plt2) = plt.subplots(2, 1, figsize=(20, 10))

# range(min, max, step)
n = range(0, 10, 1)  # domain [min, max] = [0, 9]

# make sure your functions has equal length
f = [i * 2 for i in n]
g = [i ** 2 for i in n]

# keep x-axis scale the same by specifying x-axis on the plot function.
plt1.plot(n, f) # funtion (f) range depends on it's value [min, max]
plt1.plot(n, g) # funtion (g) range depends on it's value [min, max]

# range of (f) and (g) impacts the scaling of y-axis

有关 hist 函数参数,请参阅 matplotlib.pyplot

使用 plt.xlimplt.ylim 在绘制初始图后获取当前限制,然后在绘制其他图后使用这些值设置限制:

import matplotlib.pyplot as plt

# initial data
x = [1, 2, 3, 4, 5]
y = [2, 4, 8, 16, 32]
plt.plot(x, y)

# Save the current limits here
xlims = plt.xlim()
ylims = plt.ylim()

# additional data (will change the limits)
new_x = [-10, 100]
new_y = [2, 2]
plt.plot(new_x, new_y)

# Then set the old limits as the current limits here
plt.xlim(xlims)
plt.ylim(ylims)

plt.show()

输出图(请注意 x-axis 的限制是 ~ [1, 5],即使橙色线是在 [-10, 100] 范围内定义的):

Matplotlib 有一个 autoscale() function,您可以为单独的轴对象及其单独的 x- 和 y-axes:

打开或关闭
from matplotlib import pyplot as plt

fig, (ax1, ax2) = plt.subplots(2)

#standard is that both x- and y-axis are autoscaled
ax1.plot([1, 3, 5], [2, 5, 1], label="autoscale on")
#rendering the current output
fig.draw_without_rendering() 
#turning off autoscale for the x-axis of the upper panel
#the y-axis will still be autoscaled for all following artists
ax1.autoscale(False, axis="x")
ax1.plot([-1, 7], [-2, 4], label="autoscale off")
ax1.legend()

#other axis objects are not influenced
ax2.plot([-2, 4], [3, 1])

plt.show()

示例输出:

@jfaccioni 的答案几乎是完美的(非常感谢!),但它不适用于 matplotlib 子图(如所要求的),因为 Python,不幸的是,通常没有统一的属性和方法(甚至不在同一个模块中),因此绘图和子图的 matplotlib 接口是不同的。 在此示例中,此代码适用于情节但不适用于子情节:

# this works for plots:
xlims = plt.xlim()
# and this must be used for subplots :-(
xlims = plt1.get_xlim()

因此,此代码适用于子图:

import matplotlib.pyplot as plt

fig, (plt1, plt2) = plt.subplots(2, 1, figsize=(20, 10))

# initial data
x = [1, 2, 3, 4, 5]
y = [2, 4, 8, 16, 32]
plt1.plot(x, y)

# Save the current limits here
xlims = plt1.get_xlim()
ylims = plt1.get_ylim()

# additional data (will change the limits)
new_x = [-10, 100]
new_y = [2, 2]
plt1.plot(new_x, new_y)

# Then set the old limits as the current limits here
plt1.set_xlim(xlims)
plt1.set_ylim(ylims)

plt.show()

顺便说一句:冻结 x 轴和 y 轴甚至可以通过 2 行来完成,因为再次不幸的是,python 具有不一致的属性:

# Freeze the x- and y axes:
plt1.set_xlim(plt1.get_xlim())
plt1.set_ylim(plt1.get_ylim())

将 xlim 设置为它已有的值根本没有意义。 但是因为 Python matplotlib 滥用了 xlim/ylim 属性并设置了当前绘图大小(而不是限制!),因此此代码无法按预期工作。

它有助于解决有问题的任务,但这些概念使使用 matplotlib 变得困难并且阅读 matplotlib 代码很烦人,因为必须知道隐藏的/意外的内部行为。