Python 使用线程时在matplotlib中错误填充_

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

这个问题实际上是建立在我上周发布的问题之上的。()

我试图在CAN总线上记录每秒的数据量,并将其绘制在图表上。我为这么多代码提前道歉,但我尝试的三种方法有些相似

这是一种静态情况,它起作用:

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)