使matplotlib自动缩放忽略某些绘图

2024-04-30 02:25:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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")

Tags: fromimport图形pdfplotmatplotlibfig绘制
3条回答

最明显的方法就是手动设置你想要的限制。(例如ax.axis([xmin, xmax, ymin, ymax])

如果你不想费心手动找出极限,你有两个选择。。。

正如一些人(tillsten,Yann和Vorticity)所提到的,如果你能在最后一次绘制出你想忽略的函数,那么你可以在绘制之前禁用自动缩放,或者将scaley=Falsekwarg传递给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,这样它就画在“中间”,如果你想控制它的话。

如果不想依赖于顺序,而只想指定要根据其自动缩放的行的列表,则可以执行以下操作:(注意:如果处理的是Line2D对象,而不是一般的matplotlib艺术家,则这是一个简化版本。)

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms

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

    line1, = ax.plot(x1, np.sin(x1))
    line2, = ax.plot(x1, 3 * np.sin(x1))
    line3, = ax.plot(x1, np.sin(x1 / 2.0))
    autoscale_based_on(ax, [line1, line3])

    plt.show()

def autoscale_based_on(ax, lines):
    ax.dataLim = mtransforms.Bbox.unit()
    for line in lines:
        xy = np.vstack(line.get_data()).T
        ax.dataLim.update_from_data_xy(xy, ignore=False)
    ax.autoscale_view()

if __name__ == '__main__':
    main()

enter image description here

使用scalex/scaley kw arg:

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

使用autolim=False参数可以忽略LineCollectionobjects

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

相关问题 更多 >