使matplotlib自动缩放忽略一些图

时间:2011-09-12 11:03:33

标签: python matplotlib

我使用matplotib的Axes API来绘制一些数字。我绘制的一条线代表理论预期线。它在原始y和x限制之外没有任何意义。我想要的是matlplotlib在自动缩放限制时忽略它。我以前做的是检查当前限制是什么,然后绘制并重置限制。问题在于,当我绘制第三个图时,限制会与理论线一起重新计算,这真的会扩展图形。

# Boilerplate
from matplotlib.figure import Figure
from matplotlib.backends.backend_pdf import FigureCanvasPdf
from numpy import sin, linspace


fig = Figure()
ax = fig.add_subplot(1,1,1)

x1 = linspace(-1,1,100)
ax.plot(x1, sin(x1))
ax.plot(x1, 3*sin(x1))
# I wish matplotlib would not consider the second plot when rescaling
ax.plot(x1, sin(x1/2.0))
# But would consider the first and last

canvas_pdf = FigureCanvasPdf(fig)
canvas_pdf.print_figure("test.pdf")

5 个答案:

答案 0 :(得分:14)

显而易见的方法是手动将限制设置为您想要的限制。 (例如ax.axis([xmin, xmax, ymin, ymax])

如果您不想手动找出限制,那么您有几个选择......

正如有几个人(tillsten,Yann和Vorticity)所提到的,如果您可以绘制最后要忽略的函数,那么您可以在绘制它之前禁用自动缩放或将scaley=False kwarg传递给{{1 }}

plot

请注意,您可以调整最后一个绘图的import numpy as np import matplotlib.pyplot as plt fig, ax = plt.subplots() x1 = np.linspace(-1,1,100) ax.plot(x1, np.sin(x1)) ax.plot(x1, np.sin(x1 / 2.0)) ax.autoscale(False) #You could skip this line and use scalex=False on ax.plot(x1, 3 * np.sin(x1)) #the "theoretical" plot. It has to be last either way fig.savefig('test.pdf') ,以便在“中间”绘制它,如果您想要控制它。

如果您不想依赖订单,并且您只想根据自己的指定来指定自动缩放的行列表,那么您可以执行以下操作:(注意:这是一个简化版本,假设您'重新处理zorder个对象,而不是matplotlib艺术家。)

Line2D

enter image description here

答案 1 :(得分:6)

使用scalex / scaley kw arg:

plot(x1, 3*sin(x1), scaley=False)

答案 2 :(得分:0)

LineCollection objects可以通过使用autolim=False自变量来忽略:

from matplotlib.collections import LineCollection

fig, ax = plt.subplots()
x1 = np.linspace(-1,1,100)

# Will update limits
ax.plot(x1, np.sin(x1))

# Will not update limits
col = LineCollection([np.column_stack((x1, 3 * np.sin(x1)))], colors='g')
ax.add_collection(col, autolim=False)

# Will still update limits
ax.plot(x1, np.sin(x1 / 2.0))

See this image of the output

答案 3 :(得分:0)

这可以通过创建另一个轴来完成,而与绘制顺序无关。

在此版本中,我们创建一个双轴并在该双轴上禁用自动缩放。这样,就可以根据原始轴上绘制的任何内容来缩放绘图,而不会根据放入双轴上的任何内容进行缩放。

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
x1 = np.linspace(-1,1,100)
twin_ax = ax.twinx()  # Create a twin axes.
twin_ax.autoscale(False)  # Turn off autoscaling on the twin axes.
twin_ax.set_yticks([])  # Remove the extra tick numbers from the twin axis.

ax.plot(x1, np.sin(x1))
twin_ax.plot(x1, 3 * np.sin(x1), c='green')  # Plotting the thing we don't want to scale on in the twin axes.
ax.plot(x1, np.sin(x1 / 2.0))

twin_ax.set_ylim(ax.get_ylim())  # Make sure the y limits of the twin matches the autoscaled of the original.

fig.savefig('test.pdf')

Not scaled twin axes

注意,以上内容仅防止未缠绕的轴自动缩放(在上述情况下为y)。为了使其同时适用于x和y,我们可以对x和y进行孪生过程(或从头开始创建新轴):

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
x1 = np.linspace(-1,1,100)
x2 = np.linspace(-2,2,100)  # Would extend the x limits if auto scaled
twin_ax = ax.twinx().twiny()  # Create a twin axes.
twin_ax.autoscale(False)  # Turn off autoscaling on the twin axes.
twin_ax.set_yticks([])  # Remove the extra tick numbers from the twin axis.
twin_ax.set_xticks([])  # Remove the extra tick numbers from the twin axis.

ax.plot(x1, np.sin(x1))
twin_ax.plot(x2, 3 * np.sin(x2), c='green')  # Plotting the thing we don't want to scale on in the twin axes.
ax.plot(x1, np.sin(x1 / 2.0))

twin_ax.set_ylim(ax.get_ylim())  # Make sure the y limits of the twin matches the autoscaled of the original.
twin_ax.set_xlim(ax.get_xlim())  # Make sure the x limits of the twin matches the autoscaled of the original.

fig.savefig('test.png')

答案 4 :(得分:0)

作为jam's answer的概括,可以从matplotlib的任何绘图函数中获取一个集合对象,然后用autolim=False重新添加。例如,

fig, ax = plt.subplots()
x1 = np.linspace(-1,1,100)

# Get hold of collection
collection = ax.plot(x1, np.sin(x1))

# Remove collection from the plot
collection.remove()

# Rescale
ax.relim()

# Add the collection without autoscaling
ax.add_collection(collection, autolim=False)