Python 使用线程时在matplotlib中错误填充_
这个问题实际上是建立在我上周发布的问题之上的。() 我试图在CAN总线上记录每秒的数据量,并将其绘制在图表上。我为这么多代码提前道歉,但我尝试的三种方法有些相似 这是一种静态情况,它起作用:Python 使用线程时在matplotlib中错误填充_,python,matplotlib,graph,colors,python-multithreading,Python,Matplotlib,Graph,Colors,Python Multithreading,这个问题实际上是建立在我上周发布的问题之上的。() 我试图在CAN总线上记录每秒的数据量,并将其绘制在图表上。我为这么多代码提前道歉,但我尝试的三种方法有些相似 这是一种静态情况,它起作用: import matplotlib matplotlib.use('Qt5Agg') from matplotlib import pyplot as plt import sys from collections import deque import logging import time loggi
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib import pyplot as plt
import sys
from collections import deque
import logging
import time
logging.basicConfig(level=logging.INFO)
buffer_size = 120
lvl = buffer_size * [100]
llvl = buffer_size * [95]
t = [t for t in range(buffer_size)]
bitthrough = deque(buffer_size*[0], buffer_size)
y = [107, 108, 105, 109, 107, 106, 107, 109, 106, 106, 94, 93, 94, 93, 93, 94, 95, 106, 108, 109, 107, 107, 106, 108, 105, 108, 107, 106, 107, 97, 93, 96, 94, 96, 95, 94, 104, 107, 106, 108, 107, 107, 106, 107, 105, 107, 108, 105, 107, 100, 93, 94, 93, 95, 104, 107, 107, 108, 108, 107, 107, 107, 107, 104, 94, 96, 95, 96, 94, 95, 94, 100, 107, 107, 105, 107, 107, 109, 107, 108, 107, 105, 108, 108, 106, 97, 94, 94, 94, 94, 95, 94, 94, 94, 96, 108, 108, 107, 106, 107, 107, 108, 107, 106, 95, 95, 95, 94, 94, 96, 105, 108, 107, 106, 106, 108, 107, 108, 106, 107]
bitthrough = y
fig, ax = plt.subplots()
ax.set_ylim(0, 120)
ax.set_xlim(0, 120)
ln, = plt.plot([], color='black')
plt.ion()
plt.show()
while True:
plt.pause(1)
ln.set_xdata(range(buffer_size))
ln.set_ydata(bitthrough)
wh_green = [a <= b for a,b in zip(bitthrough, llvl)]
wh_orange = [a > b and a <= c for a, b, c in zip(bitthrough, llvl, lvl)]
wh_red = [a > b for a, b, in zip(bitthrough, lvl)]
ax.fill_between(t, 0, bitthrough, where=wh_red, color='red', interpolate=True)
ax.fill_between(t, 0, bitthrough, where=wh_orange, color='orange', interpolate=True)
ax.fill_between(t, 0, bitthrough, where=wh_green, color='green', interpolate=True)
fig.canvas.draw_idle()
此代码产生以下结果:
请注意,红色是如何保持以前的最高水平的
我还尝试用matplotlib的Qt后端实现它。然而,我只是得到了一个无法更新的空图表。(没有线程,这个方法有效,但它拖累了我的计算机,使我无法做其他事情)
来自CAN总线导入PCAN的
#将numpy作为np导入
导入matplotlib
matplotlib.use('Qt5Agg')
从matplotlib导入pyplot作为plt
从matplotlib.animation导入FuncAnimation
导入系统
导入异步
从集合导入deque
导入日志记录
导入时间
导入线程
导入日期时间
从matplotlib.backends.qt_compat导入QtCore、QtWidgets
从matplotlib.backends.backend_qt5agg导入(
图CAVAS,导航工具栏2QT作为导航工具栏)
从matplotlib.figure导入图形
logging.basicConfig(级别=logging.INFO)
缓冲区大小=120
lvl=缓冲区大小*[100]
llvl=缓冲区大小*[95]
t=[t表示范围内的t(缓冲区大小)]
loop=asyncio.get\u event\u loop()
cn=PCAN()
循环。运行\u直到\u完成(cn.poll\u id())
循环。运行\u直到完成(cn.get\u names())
印刷品(cn.names)
bitthrough=deque(缓冲区大小*[0],缓冲区大小)
def get_bt(循环):
asyncio.set\u event\u循环(循环)
尽管如此:
task=loop.run\u直到完成(cn.throughput())
追加(任务[0]/33.*100.)
打印(位通过)
thread=threading.thread(target=get_bt,args=(循环,))
thread.daemon=True
thread.start()
类ApplicationWindow(QtWidgets.QMainWindow):
定义初始化(自):
super()。\uuuu init\uuuuu()
self.\u main=qtwidts.QWidget()
self.setCentralWidget(self.\u main)
layout=qtwidts.QVBoxLayout(self.\u main)
动态画布=图形画布(图(figsize=(5,3)))
layout.addWidget(动态_画布)
self.\u dynamic\u ax=dynamic\u canvas.figure.subplots()
自我更新画布()
定义更新画布(自我):
#p=循环。运行直到完成(cn.throughput())[0]/500.*100
#bitthrough.append(p)
wh_green=[a b和a b表示a,b,在zip中(比特通过,lvl)]
self.\u dynamic\u ax.clear()
self.\u dynamic\u ax.fill\u介于(t,0,位通,其中=wh\u red,color='red',interpolate=True)之间
self.\u dynamic\u ax.fill\u介于(t,0,位通,其中=wh\u orange,color='orange',interpolate=True)之间
self.\u dynamic\u ax.fill\u介于(t,0,位通,其中=wh\u green,color='green',interpolate=True)之间
自动态轴测图(t、bitthrough、color=“黑色”)
自动态最大值设置ylim(0,120)
logging.info(“重绘图形”)
self.\u dynamic\u ax.figure.canvas.draw()
如果名称=“\uuuuu main\uuuuuuuu”:
qapp=qtwidts.QApplication(sys.argv)
app=ApplicationWindow()
app.show()
qapp.exec()
尽管如此:
应用程序更新画布()
时间。睡眠(1)
这给了我这个:
也不太好,我现在有点迷路了。我发现问题是我的最后一个解决方案(使用matplotlib的Qt后端)。我打电话
while True:
app._update_canvas()
time.sleep(1)
在Qt应用程序之外。因此,图形没有得到更新,因此,一个空的图形。将app.\u update\u canvas()
移动到类内部,并使用QTimer定期调用它
正确绘制图形
添加到应用程序窗口
的\uuuuuu init\uuuuuu
功能中:
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self._update_canvas)
self.timer.start(1000)
while True:
app._update_canvas()
time.sleep(1)
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self._update_canvas)
self.timer.start(1000)