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 次 |
| 最近记录: |