使用matplotlib或pyqtgraph绘制实时数据
我有连接到串行端口的设备,我需要轮询它们,然后在绘图中显示这些数据。我目前正在使用matplotlib(缓慢地)工作。我可以连接多达64台设备,每个设备可以有20条数据需要更新。我对它进行了设置,这样就可以创建一个新窗口,并可以添加一段数据以进行打印。每打开一个额外的绘图窗口,我的更新速度就会大大降低。使用matplotlib或pyqtgraph绘制实时数据,plot,matplotlib,pyqt4,Plot,Matplotlib,Pyqt4,我有连接到串行端口的设备,我需要轮询它们,然后在绘图中显示这些数据。我目前正在使用matplotlib(缓慢地)工作。我可以连接多达64台设备,每个设备可以有20条数据需要更新。我对它进行了设置,这样就可以创建一个新窗口,并可以添加一段数据以进行打印。每打开一个额外的绘图窗口,我的更新速度就会大大降低。 我曾尝试在matplotlib中使用blit动画,但它不是真正平滑的,我可以在更新中看到异常。我尝试过PyQtGraph,但找不到任何关于如何使用此软件包的文档,现在我尝试使用PyQwt,但无法
我曾尝试在matplotlib中使用blit动画,但它不是真正平滑的,我可以在更新中看到异常。我尝试过PyQtGraph,但找不到任何关于如何使用此软件包的文档,现在我尝试使用PyQwt,但无法安装它(主要是因为我的公司不允许我们安装一个处理.gz文件的软件包)。 如有任何意见或建议,将不胜感激
import sys
from PyQt4.QtCore import (Qt, QModelIndex, QObject, SIGNAL, SLOT, QTimer, QThread, QSize, QString, QVariant)
from PyQt4 import QtGui
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from plot_toolbar import NavigationToolbar2QT as NavigationToolbar
import matplotlib.dates as md
import psutil as p
import time
import datetime as dt
import string
import ui_plotting
import pickle
try:
_fromUtf8 = QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Monitor(FigureCanvas):
"""Plot widget to display real time graphs"""
def __init__(self, timenum):
self.timenum=timenum
self.main_frame = QtGui.QWidget()
self.timeTemp1 = 0
self.timeTemp2 = 0
self.temp = 1
self.placeHolder = []
self.y_max = 0
self.y_min = 100
# initialization of the canvas
# self.dpi = 100
# self.fig = Figure((5.0, 4.0), dpi=self.dpi)
self.fig = Figure()
FigureCanvas.__init__(self, self.fig)
# self.canvas = FigureCanvas(self.fig)
# self.canvas.setParent(self.main_frame)
# first image setup
# self.fig = Figure()
# self.fig.subplots_adjust(bottom=0.5)
self.ax = self.fig.add_subplot(111)
self.mpl_toolbar = NavigationToolbar(self.fig.canvas, self.main_frame,False)
self.mpl_toolbar.setFixedHeight(24)
# set specific limits for X and Y axes
# now=dt.datetime.fromtimestamp(time.mktime(time.localtime()))
# self.timenum = now.strftime("%H:%M:%S.%f")
self.timeSec = 0
self.x_lim = 100
self.ax.set_xlim(0, self.x_lim)
self.ax.set_ylim(0, 100)
self.ax.get_xaxis().grid(True)
self.ax.get_yaxis().grid(True)
# and disable figure-wide autoscale
self.ax.set_autoscale_on(False)
self.ax.set_xlabel('Time in Seconds')
# generates first "empty" plots
self.timeb = []
self.user = []
self.l_user = []
self.l_user = [[] for x in xrange(50)]
for i in range(50):
self.l_user[i], = self.ax.plot(0,0)
# add legend to plot
# self.ax.legend()
def addTime(self,t1,t2):
timeStamp = t1+"000"
# print "timeStamp",timeStamp
timeStamp2 = t2+"000"
test = string.split(timeStamp,":")
test2 = string.split(test[2],".")
testa = string.split(timeStamp2,":")
testa2 = string.split(testa[2],".")
sub1 = int(testa[0])-int(test[0])
sub2 = int(testa[1])-int(test[1])
sub3 = int(testa2[0])-int(test2[0])
sub4 = int(testa2[1])-int(test2[1])
testing = dt.timedelta(hours=sub1,minutes=sub2,seconds=sub3,microseconds=sub4)
self.timeSec = testing.total_seconds()
def timerEvent(self, evt, timeStamp, val, lines):
temp_min = 0
temp_max = 0
# Add user arrays for each user_l array used, don't reuse user arrays
if self.y_max<max(map(float, val)):
self.y_max = max(map(float, val))
if self.y_min>min(map(float, val)):
self.y_min = min(map(float, val))
# print "val: ",val
if lines[len(lines)-1]+1 > len(self.user):
for k in range((lines[len(lines)-1]+1)-len(self.user)):
self.user.append([])
# append new data to the datasets
# print "timenum=",self.timenum
self.addTime(self.timenum, timeStamp)
self.timeb.append(self.timeSec)
for j in range((lines[len(lines)-1]+1)):
if j >49:
break
if j not in lines:
del self.user[j][:]
self.user[j].extend(self.placeHolder)
self.user[j].append(0)
else:
if len(self.timeb) > (len(self.user[j])+1):
self.user[j].extend(self.placeHolder)
self.user[j].append(str(val[lines.index(j)]))
for i in range(len(lines)):
if i>49:
break
self.l_user[lines[i]].set_data(self.timeb, self.user[lines[i]])
# force a redraw of the Figure
# if self.y_max < 2:
# self.y_max = 2
# if self.y_min < 2:
# self.y_min = 0
if self.y_min > -.1 and self.y_max < .1:
temp_min = -1
temp_max = 1
else:
temp_min = self.y_min-(self.y_min/10)
temp_max = self.y_max+(self.y_max/10)
self.ax.set_ylim(temp_min, temp_max)
if self.timeSec >= self.x_lim:
if str(self.x_lim)[0]=='2':
self.x_lim = self.x_lim * 2.5
else:
self.x_lim = self.x_lim * 2
self.ax.set_xlim(0, self.x_lim)
# self.fig.canvas.restore_region(self.fig.canvas)
# self.ax.draw_artist(self.l_user[lines[0]])
# self.fig.canvas.blit(self.ax.bbox)
self.fig.canvas.draw()
# self.draw()
self.placeHolder.append(None)
class List(QtGui.QListWidget):
def __init__(self, parent):
super(List, self).__init__(parent)
font = QtGui.QFont()
font.setFamily(_fromUtf8("Century Gothic"))
font.setPointSize(7)
self.setFont(font)
self.setDragDropMode(4)
self.setAcceptDrops(True)
self.row = []
self.col = []
self.disName = []
self.lines = []
self.counter = 0
self.setStyleSheet("background-color:#DDDDDD")
self.colors = ["blue", "green", "red", "deeppink", "black", "slategray", "sienna", "goldenrod", "teal", "orange", "orchid", "lightskyblue", "navy", "darkgreen", "indigo", "firebrick", "deepskyblue", "lightskyblue", "darkseagreen", "gold"]
def dragEnterEvent(self, e):
if e.mimeData().hasFormat("application/x-qabstractitemmodeldatalist"):
# print "currentRow : ", self.currentRow()
# print "self.col: ", self.col
# print "self.row: ", self.row
# print "self.col[]: ", self.col.pop(self.currentRow())
# print "self.row[]: ", self.row.pop(self.currentRow())
self.col.pop(self.currentRow())
self.row.pop(self.currentRow())
self.disName.pop(self.currentRow())
self.lines.pop(self.currentRow())
self.takeItem(self.currentRow())
if e.mimeData().hasFormat("application/pubmedrecord"):
e.accept()
else:
e.ignore()
def dropEvent(self, e):
items = 0
data = e.mimeData()
bstream = data.retrieveData("application/pubmedrecord", QVariant.ByteArray)
selected = pickle.loads(bstream.toByteArray())
e.accept()
# print selected
# if self.count() != 0:
# j = (self.lines[self.count()-1]%len(self.colors))+1
# else:
# j=0
while items < len(selected):
j=self.counter
if j >= len(self.colors)-1:
j = self.counter%len(self.colors)
m = len(self.lines)
self.lines.append(self.counter)
# if m != 0:
# n = self.lines[m-1]
# self.lines.append(n+1)
# else:
# self.lines.append(0)
self.col.append(str(selected[items]))
items = items+1
self.row.append(str(selected[items]))
items = items+1
self.disName.append(str(selected[items]))
listItem = QtGui.QListWidgetItem()
listItem.setText(str(selected[items]))
listItem.setTextColor(QtGui.QColor(self.colors[j]))
self.addItem(listItem)
items = items+1
self.counter += 1
def dragLeaveEvent(self, event):
event.accept()
class PlotDlg(QtGui.QDialog):
NextID = 0
filename = 'Plot'
def __init__(self,time, callback, parent=None):
super(PlotDlg, self).__init__(parent)
self.id = PlotDlg.NextID
PlotDlg.NextID += 1
self.callback = callback
self.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint)
self.setAttribute(Qt.WA_DeleteOnClose,True)
self.value = []
print "time=",time
self.time = time
self.dc = Monitor(self.time)
# self.threadPool = []
self.listWidget = List(self)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
self.listWidget.setSizePolicy(sizePolicy)
self.listWidget.setMaximumSize(QSize(150, 16777215))
grid = QtGui.QGridLayout()
grid.setSpacing(0)
grid.setContentsMargins(0, 0, 0, 0)
grid.addWidget(self.dc.mpl_toolbar,0,0,1,12)
grid.addWidget(self.listWidget,1,1)
grid.addWidget(self.dc,1,0)
grid.setColumnMinimumWidth(1,110)
self.setLayout(grid)
def update(self, clear=0):
if clear == 1:
now=dt.datetime.fromtimestamp(time.mktime(time.localtime()))
self.dc.timenum = now.strftime("%H:%M:%S.%f")
self.dc.timeSec = 0
self.dc.x_lim = 100
self.dc.y_max = 0
self.dc.y_min = 100
del self.dc.timeb[:]
del self.dc.user[:]
del self.dc.placeHolder[:]
# del self.dc.l_user[:]
# self.dc.l_user = [[] for x in xrange(50)]
# for i in range(50):
# self.dc.l_user[i], = self.dc.ax.plot(0,0)
for i in range(50):
self.dc.l_user[i].set_data(0, 0)
# print self.dc.l_user
# print self.dc.user
self.dc.ax.set_xlim(0, self.dc.x_lim)
self.dc.fig.canvas.draw()
# print self.value
# print str(self.time)
# print "time:",str(self.time)
# self.threadPool.append( GenericThread(self.dc.timerEvent,None, str(self.time), self.value, self.listWidget.lines) )
# self.threadPool[len(self.threadPool)-1].start()
self.dc.timerEvent(None, str(self.time), self.value, self.listWidget.lines)
def closeEvent(self, event):
# self.update(1)
self.callback(self.id)
PlotDlg.NextID -= 1
class GenericThread(QThread):
def __init__(self, function, *args, **kwargs):
QThread.__init__(self)
self.function = function
self.args = args
self.kwargs = kwargs
def __del__(self):
self.wait()
def run(self):
self.function(*self.args,**self.kwargs)
return
导入系统
从PyQt4.QtCore导入(Qt、QModelIndex、QObject、SIGNAL、SLOT、QTimer、QThread、QSize、QString、QVariant)
从PyQt4导入QtGui
从matplotlib.figure导入图形
从matplotlib.backends.backend_qt4agg导入FigureCanvas qtagg as FigureCanvas
从绘图工具栏导入导航工具栏2qt作为导航工具栏
将matplotlib.dates作为md导入
将psutil作为p导入
导入时间
将日期时间导入为dt
导入字符串
导入ui_绘图
进口泡菜
尝试:
_fromUtf8=QString.fromUtf8
除属性错误外:
_fromUtf8=λs:s
班长(图CAVAS):
“”“打印小部件以显示实时图形”“”
定义初始化(self,timenum):
self.timenum=timenum
self.main_frame=QtGui.QWidget()
self.timeTemp1=0
self.timeTemp2=0
self.temp=1
self.placeHolder=[]
self.y_max=0
self.y_min=100
#画布的初始化
#self.dpi=100
#self.fig=图((5.0,4.0),dpi=self.dpi)
self.fig=图()
FigureCanvas.\uuuu init\uuuuu(self,self.fig)
#self.canvas=FigureCanvas(self.fig)
#self.canvas.setParent(self.main_框架)
#第一图像设置
#self.fig=图()
#自调整图子批次(底部=0.5)
self.ax=self.fig.add_子批次(111)
self.mpl_toolbar=导航工具栏(self.fig.canvas,self.main_框架,False)
self.mpl_工具栏。设置固定高度(24)
#设置X轴和Y轴的特定限制
#now=dt.datetime.fromtimestamp(time.mktime(time.localtime()))
#self.timenum=now.strftime(“%H:%M:%S.%f”)
self.timeSec=0
self.x_lim=100
self.ax.set\u xlim(0,self.x\u lim)
self.ax.set_ylim(01100)
self.ax.get_xaxis().grid(True)
self.ax.get_yaxis().grid(True)
#并禁用图形范围的自动缩放
self.ax.set_autoscale_on(假)
self.ax.set_xlabel('以秒为单位的时间')
#生成第一个“空”图
self.timeb=[]
self.user=[]
self.l_user=[]
self.l_user=[[]表示x范围内的x(50)]
对于范围(50)内的i:
self.l_用户[i],=self.ax.plot(0,0)
#将图例添加到绘图中
#self.ax.legend()
def添加时间(自身、t1、t2):
时间戳=t1+“000”
#打印“时间戳”,时间戳
时间戳2=t2+“000”
test=string.split(时间戳“:”)
test2=string.split(test[2],“)
testa=string.split(时间戳2,“:”)
testa2=string.split(testa[2],“)
sub1=int(testa[0])-int(test[0])
sub2=int(testa[1])-int(test[1])
sub3=int(test2[0])-int(test2[0])
sub4=int(test2[1])-int(test2[1])
测试=dt.timedelta(小时=sub1,分钟=sub2,秒=sub3,微秒=sub4)
self.timeSec=测试。总秒数()
def TIMEVERENT(自身、evt、时间戳、val、行):
最低温度=0
最高温度=0
#为使用的每个用户数组添加用户数组,不要重用用户数组
如果self.y_maxmin(map(float,val)):
self.y_min=min(映射(浮点,val))
#打印“val:”,val
如果行[len(lines)-1]+1>len(self.user):
对于范围内的k((行[len(lines)-1]+1)-len(self.user)):
self.user.append([])
#将新数据附加到数据集
#打印“timenum=”,self.timenum
self.addTime(self.timenum,timeStamp)
self.timeb.append(self.timeSec)
对于范围内的j((线[len(线)-1]+1)):
如果j>49:
打破
如果j不在直线上:
del self.user[j][:]
self.user[j].extend(self.placeHolder)
self.user[j].追加(0)
其他:
如果len(self.timeb)>(len(self.user[j])+1):
self.user[j].extend(self.placeHolder)
self.user[j].append(str(val[lines.index(j)])
对于范围内的i(len(行)):
如果i>49:
打破
self.l_用户[lines[i]]。设置_数据(self.timeb,self.user[lines[i]])
#强制重新绘制图形
#如果self.y_max<2:
#self.y_max=2
#如果self.y_min<2:
#self.y_min=0
如果self.y_最小值>-.1且self.y_最大值<.1:
最低温度=-1
最高温度=1
其他:
最低温度=最低自我温度-(最低自我温度/10)
温度最大值=自身y最大值+(自身y最大值/10)
自最大设定值(最低温度、最高温度)
如果self.timeSec>=self.x_lim:
如果str(self.x_lim)[0]=“2”:
self.x_lim=self.x_lim*2.5
其他:
self.x_lim=self.x_lim*2
self.ax.set\u xlim(0,self.x\u lim)
#self.fig.canvas.restore_区域(self.fig.canvas)
#self.ax.draw_艺术家(self.l_用户[lines[0]])
#self.fig.canvas.blit(self.ax.bbox)
self.fig.canvas.draw()
#self.draw()
self.placeHolder.append(无)
类列表(QtGui.QListWidget):
定义初始化(自身,父级):
超级(列表,自我)。\uuuuu初始化\uuuuuuu(父级)
font=QtGui.QFont()
font.setFamily(_fromUtf8(“世纪哥特式”))
font.setPointSize(7)
self.setFont(字体)
self.setDragDropMode(4)
self.setAcceptDrops(真)
self.row=[]
self.col=[]
self.disName=[]
self.lines=[]
self.counter=0
self.setStyleSheet(“背景色:#DDDDDD”)
self.colors=[“蓝色”、“绿色”、“红色”、“深粉色”、“黑色”、“灰色”,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
data = np.zeros((32,100))
X = np.arange(data.shape[-1])
# Generate line plots
lines = []
for i in range(len(data)):
# Each plot each shifter upward
line, = ax.plot(X,i+data[i], color=".75")
lines.append(line)
# Set limits
ax.set_ylim(0,len(data))
ax.set_xlim(0,data.shape[-1]-1)
# Update function
def update(*args):
# Shift data left
data[:,:-1] = data[:,1:]
# Append new values
data[:,-1] = np.arange(len(data))+np.random.uniform(0,1,len(data))
# Update data
for i in range(len(data)):
lines[i].set_ydata(data[i])
ani = animation.FuncAnimation(fig, update,interval=10)
plt.show()