gpt4 book ai didi

Python 从线程更新 Matplotlib

转载 作者:太空宇宙 更新时间:2023-11-04 04:50:45 25 4
gpt4 key购买 nike

我是 python 世界的新手,不幸的是我还找不到任何解决方案。

我在 Mac OS X 10.13.2 上使用 matplotlib==1.3.1 运行 python 3.6

目前我正在尝试构建一个小型软件,它以 4Hz 的频率获取数据并以 1Hz 的频率在绘图中显示获取的数据。因此我创建了一个在线程中运行的类来获取数据和另一个类来更新实际的图。在两者之间有一个数据类,它将保存数据并用作两个类之间的接口(interface)。

import matplotlib.pyplot as plt
import numpy as np
import threading
import random
import time

class MyDataClass():

def __init__(self):

self.XData = [0]
self.YData = [0]


class MyPlotClass(threading.Thread):

def __init__(self, dataClass):

threading.Thread.__init__(self)

self._dataClass = dataClass
self._period = 1
self._nextCall = time.time()

self.hLine, = plt.plot(0, 0)

plt.ion()

def run(self):

while True:
self.hLine.set_data(self._dataClass.XData, self._dataClass.YData)
plt.draw()
print("updated %i datapoints" % len(self._dataClass.XData))
# sleep until next execution
self._nextCall = self._nextCall + self._period
time.sleep(self._nextCall - time.time())


class MyDataFetchClass(threading.Thread):

def __init__(self, dataClass):

threading.Thread.__init__(self)

self._dataClass = dataClass
self._period = 0.25
self._nextCall = time.time()

def run(self):

while True:
# add data to data class
self._dataClass.XData.append(self._dataClass.XData[-1] + 1)
self._dataClass.YData.append(random.randint(0, 256))
print("Added (%i, %i)" % (self._dataClass.XData[-1], self._dataClass.YData[-1]))
# sleep until next execution
self._nextCall = self._nextCall + self._period
time.sleep(self._nextCall - time.time())


data = MyDataClass()
fetcher = MyDataFetchClass(data)
plotter = MyPlotClass(data)

fetcher.start()
plotter.start()

fetcher.join()
plotter.join()

由于命令行输出,我可以看到线程正在运行。但出于某种原因,持有地 block 的人物不会出现。

火箭符号只会上下弹跳而不是出现。请参阅随附的屏幕截图。

仅创建绘图并使用 plt.show() 命令的简单示例效果很好。

我不知道我做错了什么。我希望你们中的任何人都有想法。

谢谢!

编辑:此处提供的解决方案 How to update a plot in matplotlib?对我不起作用,因为我不想被限制在一定数量的帧(使用 Matplotlib 的动画框架)。我需要用 1Hz 连续更新绘图。

Figure not showing up

最佳答案

我不认为你可以在主线程之外运行 matplotlib GUI。因此,将绘图保留在主线程中并使用 FuncAnimation 来引导绘图,以下似乎工作正常。

由于 while True 循环,它会一直运行,即使在关闭窗口后也是如此,因此对于任何现实世界的应用程序,仍应对此进行调整。

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
import threading
import random
import time

class MyDataClass():

def __init__(self):

self.XData = [0]
self.YData = [0]


class MyPlotClass():

def __init__(self, dataClass):

self._dataClass = dataClass

self.hLine, = plt.plot(0, 0)

self.ani = FuncAnimation(plt.gcf(), self.run, interval = 1000, repeat=True)


def run(self, i):
print("plotting data")
self.hLine.set_data(self._dataClass.XData, self._dataClass.YData)
self.hLine.axes.relim()
self.hLine.axes.autoscale_view()


class MyDataFetchClass(threading.Thread):

def __init__(self, dataClass):

threading.Thread.__init__(self)

self._dataClass = dataClass
self._period = 0.25
self._nextCall = time.time()


def run(self):

while True:
print("updating data")
# add data to data class
self._dataClass.XData.append(self._dataClass.XData[-1] + 1)
self._dataClass.YData.append(random.randint(0, 256))
# sleep until next execution
self._nextCall = self._nextCall + self._period;
time.sleep(self._nextCall - time.time())


data = MyDataClass()
plotter = MyPlotClass(data)
fetcher = MyDataFetchClass(data)

fetcher.start()
plt.show()
#fetcher.join()

关于Python 从线程更新 Matplotlib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48389470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com