Row*_*iek 5 python matplotlib python-3.x
我试图嵌入一个matplotlib图,每秒更新一次PyQt GUI主窗口.
在我的程序中,我threading.Timer
通过timer
下面显示的函数每秒调用一次更新函数.我有一个问题:我的程序每秒都会变大 - 每4秒钟大约1k.我最初的想法是append函数(返回一个新数组update_figure
)不会删除旧数组?这可能是我问题的原因吗?
def update_figure(self):
self.yAxis = np.append(self.yAxis, (getCO22()))
self.xAxis = np.append(self.xAxis, self.i)
# print(self.xAxis)
if len(self.yAxis) > 10:
self.yAxis = np.delete(self.yAxis, 0)
if len(self.xAxis) > 10:
self.xAxis = np.delete(self.xAxis, 0)
self.axes.plot(self.xAxis, self.yAxis, scaley=False)
self.axes.grid(True)
self.i = self.i + 1
self.draw()
Run Code Online (Sandbox Code Playgroud)
这是我的计时器功能 - 这是通过点击我的PyQt GUI中的按钮触发,然后调用自己,如您所见:
def timer(self):
getCH4()
getCO2()
getConnectedDevices()
self.dc.update_figure()
t = threading.Timer(1.0, self.timer)
t.start()
Run Code Online (Sandbox Code Playgroud)
编辑:我无法发布我的整个代码,因为它需要很多.dll包含.所以我将尝试解释这个程序的功能.
在我的GUI中,我想显示我的CO 2值随着时间的推移.我的get_co22
函数只返回一个浮点值,我100%肯定这个工作正常.使用我的计时器,如上所示,我想继续为matplotlib图添加一个值 - 该Axes
对象可供我使用self.axes
.我尝试绘制数据的最后10个值.
编辑2:在聊天中进行了一些讨论后,我尝试将调用update_figure()
放在一个while
循环中,只使用一个线程来调用它,并且能够创建这个最小的例子 http://pastebin.com/RXya6Zah.这改变了代码的结构以调用update_figure()
以下内容:
def task(self):
while True:
ui.dc.update_figure()
time.sleep(1.0)
def timer(self):
t = Timer(1.0, self.task())
t.start()
Run Code Online (Sandbox Code Playgroud)
但现在程序在5次迭代后崩溃了.
问题绝对不在于如何附加到 numpy 数组或截断它。
这里的问题在于你的线程模型。将计算循环与 GUI 控制循环集成起来很困难。
从根本上讲,您需要 GUI 线程来控制何时调用更新代码(如有必要,生成一个新线程来处理它) - 这样
在这种情况下,由于您的主窗口是由PyQt4控制的,因此您需要使用QTimer
(请参阅此处的简单示例)
所以 - 将您的timer
代码更改为
def task(self):
getCH4()
getCO2()
getConnectedDevices()
self.dc.update_figure()
def timer(self):
self.t = QtCore.QTimer()
self.t.timeout.connect(self.task)
self.t.start(1000)
Run Code Online (Sandbox Code Playgroud)
这应该有效。保留对 的引用QTimer
至关重要 - 因此self.t = QtCore.QTimer()
而不是t = QtCore.QTimer()
,否则该QTimer
对象将被垃圾收集。
这是聊天中一个长线程的总结,澄清了问题并研究了几种可能的解决方案。特别是 - OP 设法在这里模拟了一个更简单的可运行示例: http: //pastebin.com/RXya6Zah
完整可运行示例的固定版本在这里: http: //pastebin.com/gv7Cmapr
相关代码和解释位于上面,但这些链接可能会帮助任何想要复制/解决问题的人。请注意,它们需要安装 PyQt4