使用matplotlib或pyqtgraph绘制实时数据

使用matplotlib或pyqtgraph绘制实时数据,plot,matplotlib,pyqt4,Plot,Matplotlib,Pyqt4,我有连接到串行端口的设备,我需要轮询它们,然后在绘图中显示这些数据。我目前正在使用matplotlib(缓慢地)工作。我可以连接多达64台设备,每个设备可以有20条数据需要更新。我对它进行了设置,这样就可以创建一个新窗口,并可以添加一段数据以进行打印。每打开一个额外的绘图窗口,我的更新速度就会大大降低。 我曾尝试在matplotlib中使用blit动画,但它不是真正平滑的,我可以在更新中看到异常。我尝试过PyQtGraph,但找不到任何关于如何使用此软件包的文档,现在我尝试使用PyQwt,但无法

我有连接到串行端口的设备,我需要轮询它们,然后在绘图中显示这些数据。我目前正在使用matplotlib(缓慢地)工作。我可以连接多达64台设备,每个设备可以有20条数据需要更新。我对它进行了设置,这样就可以创建一个新窗口,并可以添加一段数据以进行打印。每打开一个额外的绘图窗口,我的更新速度就会大大降低。
我曾尝试在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()