图 GUI 冻结
Posted
技术标签:
【中文标题】图 GUI 冻结【英文标题】:Figure GUI freezing 【发布时间】:2013-01-16 20:03:32 【问题描述】:我是 python 的新手,我正在尝试根据存储在文件中的数据绘制一个图。这个文件可能随时更新,所以我试图让绘图每 3 秒更新一次(所以我不使用所有 CPU)。我的问题是午餐后 GUI 冻结了。
#!/usr/bin/python
# _*_ coding: utf8 _*_
import matplotlib.pyplot as plt
import numpy as np
import time
plt.ion()
plt.figure()
i=0
while 1:
taille=0
fichier=np.loadtxt('data/US.SAVE')
fichier1=np.loadtxt('data/cond.SAVE')
taille1=np.size(fichier1[:,1])
taille=np.size(fichier[:,1])
min=min(fichier[0,0],fichier1[0,0]);
fichier[:,0]=fichier[:,0]-min
fichier1[:,0]=fichier1[:,0]-min
if (taille != taille1) :
printErrors("TAILLE DE FICHIERS DIFFERENTES")
nb_chunks=np.size(fichier1[1,:])
nb_inputs=np.size(fichier[1,:])
plt.subplot(3,1,1)
plt.bar(fichier[:,0],fichier[:,1],align='center',width=0.0001, facecolor='b', label="US")
x1,x2,y1,y2 = plt.axis()
x1=x1-0.0001
plt.axis([x1, x2, y1, 1.2])
plt.legend(ncol=3,prop='size':9)
plt.title("US ")
plt.ylabel('Activation')
plt.xlabel('Time')
plt.subplot(3,1,2)
plt.bar(fichier1[:,0],fichier1[:,1],align='center',width=0.0001, facecolor='b', label="response")
plt.axis([x1, x2, y1, 1.2])
plt.legend(ncol=3,prop='size':9)
plt.title("Response ")
plt.ylabel('Activation')
plt.xlabel('Time')
plt.subplot(3,1,3)
plt.bar(fichier[:,0]-fichier1[:,0],fichier1[:,1],align='center',width=0.0001, facecolor='b', label="Error")
plt.axis([x1, x2, y1, 1.2])
plt.legend(ncol=3,prop='size':9)
plt.title("Error")
plt.ylabel('Activation')
plt.xlabel('Time')
plt.draw()
name1='data/Conditionnement.eps'
plt.savefig(name1,dpi=256)
plt.draw()
del fichier,fichier1,min
i=i+1
time.sleep(3)
plt.show()
我没有在基于文件的绘图上找到任何其他主题。
【问题讨论】:
您解决了吗?如果是这样,您应该接受其中一个答案。 pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs 的可能重复项 【参考方案1】:您想使用plt.pause(3)
函数而不是time.sleep()
。 pause
包括对 gui 主循环的必要调用,以重新绘制图形。
另见:Python- 1 second plots continous presentation、matplotlib real-time linear line、pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs、
【讨论】:
我不认为plt.show()
是问题,因为他/她正在使用交互模式并且代码中很少有plt.draw()
我确认使用plt.pause
正确重绘了情节
@FrancescoMontesano 感谢您的关注。【参考方案2】:
在@tcaswell 的回答之上(解决问题),我建议以更面向对象的方式重新考虑脚本。
我试过这个:
plt.ion()
plt.figure()
plt.show()
while True:
x=np.arange(10)
y=np.random.rand(10)
plt.subplot(121)
plt.plot(x,y)
plt.subplot(122)
plt.plot(x,2*y)
plt.draw()
plt.pause(3)
但它不起作用(看起来它在plt.figure
打开一个 gui,然后在每个循环中。
这样的解决方案:
plt.ion()
fig, ax = plt.subplots(nrows=2, ncols=1)
plt.show()
while True:
x=np.arange(10)
y=np.random.rand(10)
ax[0].plot(x,y)
ax[1].plot(x,2*y)
plt.draw()
plt.pause(3)
效率更高(轴只创建一次),更整洁(最后 matplotlib 是 OO)并且可能不太容易发生内存泄漏。
此外,我从您的大部分信息中收集到,在每个循环中您再次读取文件,然后绘制新行。如果是这种情况,您需要在重绘之前先清除轴的内容。在我的简单情况下,您可以使用
清除轴for a in ax:
a.clear()
【讨论】:
+1 如果你打算这样做,你可以做得更好,保存Line2d
对象并重新使用它们。
@tcaswell:你的意思是这样的吗? l = ax.plot(x,y)
第一次和l.set_data(x, y)
在以下所有循环中?要自动重置轴限制可以做ax.relim()
; ax.autoscale()
是的,类似的。请参阅我的答案或任何动画示例中的链接。以上是关于图 GUI 冻结的主要内容,如果未能解决你的问题,请参考以下文章