der*_*lix 3 python macos multithreading matplotlib python-multithreading
我对 python 世界还很陌生,不幸的是我还找不到任何解决方案。
我在 Mac OS X 10.13.2 上运行 python 3.6 和 matplotlib==1.3.1
目前我正在尝试构建一个小型软件,它以 4Hz 的频率获取数据,并以 1Hz 的频率在绘图中显示获取的数据。因此,我创建了一个在线程中运行的类来获取数据,并创建了另一个类来更新实际的绘图。中间有一个数据类,它将保存数据并用作两个类之间的接口。
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()
Run Code Online (Sandbox Code Playgroud)
由于命令行输出,我可以看到线程正在运行。但由于某种原因,持有地块的人物不会出现。
火箭符号只会上下弹跳,而不是显示出来。请参阅随附的屏幕截图。
仅创建绘图并使用 plt.show() 命令的简单示例可以正常工作。
我不明白我做错了什么。我希望你们中的任何人都有一个想法。
谢谢!
编辑:此处提出的解决方案如何更新 matplotlib 中的绘图?对我不起作用,因为我不想限制在一定数量的帧(使用 Matplotlib 的动画框架)。我需要以 1Hz 连续更新绘图。
我认为你不能在主线程之外运行 matplotlib GUI。因此,将绘图保留在主线程中并使用 aFuncAnimation
来引导绘图,以下内容似乎工作正常。
由于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()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9985 次 |
最近记录: |