回答
是的,这是 matplotlib 图形的正常预期行为。
说明
当您运行plt.plot(...) 时,一方面会创建实际情节的lines 实例:
>>> print( plt.plot(year, pop) )
[<matplotlib.lines.Line2D object at 0x000000000D8FDB00>]
...另一方面是Figure 实例,它被设置为“当前图形”,可通过plt.gcf()(“获取当前图形”的缩写)访问:
>>> print( plt.gcf() )
Figure(432x288)
线条(以及您可能添加的其他绘图元素)都放置在当前图形中。当plt.show() 被调用时,当前图形会显示然后清空(!),这就是为什么第二次调用plt.show() 不会绘制任何东西。
标准解决方法
解决此问题的一种方法是显式保留当前的Figure 实例,然后直接使用fig.show() 显示它,如下所示:
plt.plot(year, pop)
fig = plt.gcf() # Grabs the current figure
plt.show() # Shows plot
plt.show() # Does nothing
fig.show() # Shows plot again
fig.show() # Shows plot again...
更常用的替代方法是在开始时显式初始化当前图形,在任何绘图命令之前。
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
fig.show() # Shows plot again
这通常与图形的一些附加参数的规范相结合,例如:
fig = plt.figure(figsize=(8,8))
对于 Jupyter 笔记本用户
fig.show() 方法在 Jupyter Notebooks 的上下文中可能不起作用,并且可能会产生以下警告并且不显示绘图:
C:\redacted\path\lib\site-packages\matplotlib\figure.py:459:
用户警告:matplotlib 当前使用的是非 GUI 后端,所以
无法显示图
幸运的是,只需在代码单元格的末尾写入fig(而不是fig.show())即可将图形推送到单元格的输出并显示它。如果需要在同一个代码单元格内多次显示,可以使用display函数达到同样的效果:
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
plt.show() # Does nothing
from IPython.display import display
display(fig) # Shows plot again
display(fig) # Shows plot again...
使用函数
想要多次show 一个数字的一个原因是每次都要进行各种不同的修改。这可以使用上面讨论的fig 方法来完成,但对于更广泛的绘图定义,通常更容易将基本图形简单地包装在一个函数中并重复调用它。
例子:
def my_plot(year, pop):
plt.plot(year, pop)
plt.xlabel("year")
plt.ylabel("population")
my_plot(year, pop)
plt.show() # Shows plot
my_plot(year, pop)
plt.show() # Shows plot again
my_plot(year, pop)
plt.title("demographics plot")
plt.show() # Shows plot again, this time with title