问题描述
因此,我有一个散布一些数据并通过创建新图形来实现的功能。一次最多允许输入20个数字,以避免内存过载。如果用户想绘制一个包含6个变量的数据集,那么会有30个不同的数字。有没有办法等到用户删除必要数量的图形之后再添加更多图形?
这就是我想要的:
import matplolib.pyplot as plt
... # some code
# this below is inside a loop structure
f = plt.figure
# add some stuff to the figure
plt.show(block=False)
Halt() # checks to see if there are too many figures
其中Halt()的定义如下:
def halt():
first = True
while plt.gcf().number > 20: # are there more than 20 figures
if first:
# show message
first = False
# time.sleep(100)
唯一的问题是它“冻结”程序,不允许用户退出任何图中,因为它“没有响应”。我也尝试过time.sleep()
,但这似乎也不起作用。
有人知道在满足条件之前循环播放的好方法吗?
解决方法
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.show.html说:
如果
False
确保显示所有窗口并立即返回。在这种情况下,您有责任确保事件循环正在运行以具有可响应的数字。
如何做到这一点,你问?好吧,文档位于https://matplotlib.org/users/interactive_guide.html#explicitly-spinning-the-event-loop。
经过一番摆弄之后,我进行了以下操作,同时绘制了20个图形,其中最多5个图形:
import matplotlib.pyplot as plt
import numpy as np
from time import sleep
def plot_stuff(exponent,titlenum):
x = np.linspace(0.0,1.0)
f = plt.figure()
ax = f.add_subplot(1,1,1)
ax.set_title('{} - {}'.format(titlenum,exponent))
ax.plot(x,x**exponent)
def get_fighandles():
fignumbers = plt.get_fignums()
return [plt.figure(fign) for fign in fignumbers]
N_figs_eventually_plotted = 20
N_figs_max_simultaneous = 5
N=0
while N < N_figs_eventually_plotted:
if len(get_fighandles()) < N_figs_max_simultaneous:
N += 1
# put here whichever update is needed when you can add new figures
plot_stuff(np.random.random(),N)
plt.show(block=False)
print('hi')
for fig in get_fighandles():
print(fig.canvas)
fig.canvas.flush_events()
fig.canvas.draw_idle() # might not be needed,but here it's fast
sleep(0.1)
# note: solution terminates when the last figure is plotted,you might want something to prevent this (for instance a plt.show(block=True) when the last figure is plotted)
可能存在一些细微的并发错误(例如,如果在循环读取图句柄之后但在刷新事件之前关闭图),但我看不出如何在用例中避免这种情况。 / p>