图 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 冻结的主要内容,如果未能解决你的问题,请参考以下文章

Kivy GUI 冻结

Pyqt Gui 在循环中冻结

并发插入冻结 GUI(Windows 应用程序/PostgreSQL)

为啥即使使用 QThreadPool,GUI 也会冻结?

无需冻结gui的简单任务

如何修复 PyQt5 GUI 冻结