Figure.show、Figure.canvas.draw 和Figure.canvas.draw_idle 之间有什么区别

Ari*_*ief 10 canvas matplotlib

Figure在 Matplotlib 中,我可以通过调用对象(例如,fig调用方法show( ))来更新图中绘图的视觉效果fig.show()。但我也可以通过调用canvas图中的对象然后调用方法draw( fig.canvas.draw()) 来做到这一点。

例子:

import matplotlib.pyplot as plt

fig, axes = plt.subplots()
axes.plot([1,2,3],[2,3,4])
fig.show()
axes.plot([1,2,3],[-2,23,14])
fig.show()
Run Code Online (Sandbox Code Playgroud)

import matplotlib.pyplot as plt

fig, axes = plt.subplots()
axes.plot([1,2,3],[2,3,4])
fig.show()
axes.plot([1,2,3],[-2,23,14])
fig.canvas.draw()
Run Code Online (Sandbox Code Playgroud)

我怀疑他们fig.show也会表演self.canvas.draw()和其他一些事情。但是当我检查代码时,我只看到它可能会调用self.canvas.draw_idle().

fig.show, fig.canvas.draw,之间有什么区别fig.canvas.draw_idle??

ram*_*eek 5

当我调用fig.show()从命令行运行的 python 脚本(在 Windows 上的 Anaconda 中)时,它会短暂地从我的屏幕上出现并消失。这与plt.show()显示所有打开的图形不同,Python 脚本会挂起,直到我关闭它们以继续运行。(我知道您没有plt.show()在上面讨论,但为了清晰和完整而想提及它。)

fig.show()调用plt.canvas.draw_idle(),它“安排 GUI 窗口下次重新绘制屏幕时进行渲染”,从而fig.canvas.draw()在某些条件下调用。事实上,同一个链接继续指出“即使在控制返回到 GUI 事件循环之前发生对 draw_idle 的多次调用,该图形也只会渲染一次”。为了确保屏幕尽快更新,文档建议fig.canvas.draw_idle后面应加上fig.canvas.flush_events().

相比之下,fig.canvas.draw()即使没有产生输出,也会渲染图形。查看文档,该函数渲染图形并“即使没有生成输出,也会在艺术家树上行走,因为这将触发延迟工作(例如计算限制自动限制和刻度值)”。因此,您可以在内存中生成图形,而不是实际显示或打印它。我见过的唯一有用的例子是当您在最终渲染和打印/保存之前需要有关图形格式的详细信息时。

根据这些信息,我做了一个计时实验:

import matplotlib.pyplot as plt
import datetime

N = 10**4

fig, axes = plt.subplots()
axes.plot([1,2,3],[2,3,4])

a = datetime.datetime.now()
for i in range(N):
    fig.show()
b = datetime.datetime.now()
print("fig.show:               ", b-a)
a = datetime.datetime.now()

for i in range(N):
    fig.canvas.draw_idle()
b = datetime.datetime.now()
print("fig.canvas.draw_idle:   ", b-a)

a = datetime.datetime.now()
for i in range(N):
    fig.canvas.draw()
b = datetime.datetime.now()
print("fig.canvas.draw:        ", b-a)


for i in range(N):
    fig.canvas.draw_idle()
    fig.canvas.flush_events()
b = datetime.datetime.now()
print("draw_idle, flush_events:", b-a)

# fig.show:                0:00:00.280800
# fig.canvas.draw_idle:    0:00:00.015600
# fig.canvas.draw:         0:03:43.450512
# draw_idle, flush_events: 0:08:29.103440

Run Code Online (Sandbox Code Playgroud)

根据这些时间安排,您可以明白为什么文档建议在大多数情况下使用fig.canvas.draw_idle()over 。fig.canvas.draw()