在添加更多之前等到用户删除 Matplotlib 图的方法?
Way to wait until user deletes Matplotlib figure before adding more?
所以我有一个函数可以散点图绘制一些数据,并通过创建新图形来实现。一次允许的最大数字量为 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 说:
If False
ensure that all windows are displayed and return immediately. In this case, you are responsible for ensuring that the event loop is running to have responsive figures.
如何做到这一点,你问?好吧,文档位于 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)
可能存在一些微妙的并发错误(例如,如果您在循环读取图窗句柄之后但在刷新事件之前关闭图窗),但我看不出如何在您的用例中避免这种情况.
所以我有一个函数可以散点图绘制一些数据,并通过创建新图形来实现。一次允许的最大数字量为 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 说:
If
False
ensure that all windows are displayed and return immediately. In this case, you are responsible for ensuring that the event loop is running to have responsive figures.
如何做到这一点,你问?好吧,文档位于 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)
可能存在一些微妙的并发错误(例如,如果您在循环读取图窗句柄之后但在刷新事件之前关闭图窗),但我看不出如何在您的用例中避免这种情况.