python升级matplotlib_Python从线程更新Matplotlib

I'm pretty new to the python world and unfortunately I could not find any solution to this yet.

I'm running python 3.6 with matplotlib==1.3.1 on Mac OS X 10.13.2

Currently I'm trying to build a small software which fetches data at 4Hz and displays the fetched data in a plot at 1Hz. Therefore I created a class which runs in a thread to fetch the data and another class to update the actual plots. In-between there is a data class which will hold the data and is used as interface inbetween the two classes.

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()

I can see that the threads are running due to the command line output. But for some reason the figure holding the plots won't show up.

The rocket symbol will just bounce up and down instead of showing up. See attached Screenshot.

Simple examples where the plot is only created ones and the plt.show() command is used works fine.

I can't figure out what I'm doing wrong. I hope anyone of you might have an idea.

Thanks!

Edit: Solutions presented here How to update a plot in matplotlib? will not work for me because I don't want to be limited to a certain number of frames (using the animation framework of Matplotlib). I need to update the plot with 1Hz continiously.

解决方案

I don't think you can run matplotlib GUI outside the main thread. So keeping the plotting in the main thread and using a FuncAnimation to steer the plotting, the following seems to work fine.

Due to the while True loop it will run forever, even after closing the window, so for any real world application this should still be adjusted.

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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值