在调用 pyplot.show()之后保存图形将导致一个空文件

下面的示例代码生成一个简单的绘图,然后将其保存为‘ fig1.pdf’,然后显示它,再将其保存为‘ fig2.pdf’。第一个图像看起来和预期的一样,但是第二个图像是空白的(包含一个白色正方形)。这到底是怎么回事?线路 plt.show()显然搞砸了一些事情,但我不能搞清楚是什么/怎么搞的!

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')
66758 次浏览

Show 块并在关闭时销毁该图

plt.show(block=False)

之后保存到 fig2.pdf 将工作,或者您可以在保存之前重新绘制它

plt.plot(x,y)
plt.savefig('fig2.pdf')

如果希望在显示图形之后保存它,则需要保存图形实例。在调用 show之后 plt.savefig不工作的原因是当前的数字已经被重置。

pyplot在幕后跟踪哪些数字、轴等是“当前”的(即尚未用 show显示)。gcfgca show0et show1urrent show2igure 和当前 show3xes 实例,分别。plt.savefig(基本上任何其他 pyplot方法)只做 plt.gcf().savefig(...)。换句话说,获取当前的图实例并调用它的 savefig方法。类似地,plt.plot基本上做 plt.gca().plot(...)

调用 show之后,“当前”数字和轴的列表为空。

通常,最好直接使用图形和轴实例绘制/保存/显示/等,而不是使用 plt.plot等隐式地获取当前的图形/轴并对其进行绘制。使用 pyplot做任何事情都没有错(特别是交互式的) ,但是它使你更容易搬起石头砸自己的脚。

对于 plt.show()使用 pyplot并生成图形和轴对象,但随后直接使用图形或轴方法。(例如 ax.plot(x, y)而不是 plt.plot(x, y)等等)这样做的主要优点是它是显式的。您知道正在绘制的对象,并且不必推断 pyplot 状态机的作用(尽管理解状态机接口也不是那么困难)。

作为“推荐”做事方式的一个例子,可以这样做:

import numpy as np
import matplotlib.pyplot as plt


x = np.linspace(-1, 1, 100)
y = x**2


fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')

如果您希望使用 pyplot接口处理所有事情,那么在调用 show之前只需获取图实例即可。例如:

import numpy as np
import matplotlib.pyplot as plt


x = np.linspace(-1, 1, 100)
y = x**2


plt.plot(x, y)
fig = plt.gcf()
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')

我必须运行 plt.cla()plt.clf()才能绘制第二个。分别清除电流轴和电流图。

如果您只是想在保存之前看到数字,您可以打电话

plt.ion()

在绘图之前,其中 开始交互模式显示所有绘制的图形。这主要消除了调用 plt.show()的需要。您不再需要关闭数字才能继续。

若要再次禁用交互模式,请调用 plt.ioff()