Python3.x+pyqtgraph实现数据可视化教程
1、pyqtgraph库数据可视化效果还不错,特别是窗体程序中图像交互性较好;安装也很方便,用pip安装。
2、在Python中新建一个.py文件,然后写入如下代码并执行可以得到官方提供的很多案例(含代码),出现如下界面图像:
importpyqtgraph.examples
pyqtgraph.examples.run()
图1
图2
图3
4、程序默认是黑色背景,这个是可以修改的。比如,在程序的开头部分写入如下代码就可以修改背景:
pg.setConfigOption('background','w')
pg.setConfigOption('foreground','k')
更多说明,见pyqtgraph官网:http://www.pyqtgraph.org/documentation/style.html,“Line,Fill,andColor”部分的“DefaultBackgroundandForegroundColors”部分。
5、一个修改背景颜色的完整案例如下,可以直接运行程序:
importnumpyasnp importpyqtgraphaspg frompyqtgraph.QtimportQtGui,QtCore #如下2行代码是我自己加入的,目的是修改默认的黑色背景为其它颜色背景 pg.setConfigOption('background','w') pg.setConfigOption('foreground','k') frompyqtgraph.PointimportPoint #generatelayout app=QtGui.QApplication([]) win=pg.GraphicsWindow() win.setWindowTitle('pyqtgraphexample:crosshair') label=pg.LabelItem(justify='right') win.addItem(label) p1=win.addPlot(row=1,col=0) p2=win.addPlot(row=2,col=0) region=pg.LinearRegionItem() region.setZValue(10) #AddtheLinearRegionItemtotheViewBox,buttelltheViewBoxtoexcludethis #itemwhendoingauto-rangecalculations. p2.addItem(region,ignoreBounds=True) #pg.dbg() p1.setAutoVisible(y=True) #createnumpyarrays #makethenumberslargetoshowthatthexrangeshowsdatafrom10000toalltheway0 data1=10000+15000*pg.gaussianFilter(np.random.random(size=10000),10)+3000*np.random.random(size=10000) data2=15000+15000*pg.gaussianFilter(np.random.random(size=10000),10)+3000*np.random.random(size=10000) p1.plot(data1,pen="r") p1.plot(data2,pen="g") p2.plot(data1,pen="w") defupdate(): region.setZValue(10) minX,maxX=region.getRegion() p1.setXRange(minX,maxX,padding=0) region.sigRegionChanged.connect(update) defupdateRegion(window,viewRange): rgn=viewRange[0] region.setRegion(rgn) p1.sigRangeChanged.connect(updateRegion) region.setRegion([1000,2000]) #crosshair vLine=pg.InfiniteLine(angle=90,movable=False) hLine=pg.InfiniteLine(angle=0,movable=False) p1.addItem(vLine,ignoreBounds=True) p1.addItem(hLine,ignoreBounds=True) vb=p1.vb defmouseMoved(evt): pos=evt[0]##usingsignalproxyturnsoriginalargumentsintoatuple ifp1.sceneBoundingRect().contains(pos): mousePoint=vb.mapSceneToView(pos) index=int(mousePoint.x()) ifindex>0andindexx=%0.1f, y1=%0.1f, y2=%0.1f"%(mousePoint.x(),data1[index],data2[index])) vLine.setPos(mousePoint.x()) hLine.setPos(mousePoint.y()) proxy=pg.SignalProxy(p1.scene().sigMouseMoved,rateLimit=60,slot=mouseMoved) #p1.scene().sigMouseMoved.connect(mouseMoved) ##StartQteventloopunlessrunningininteractivemodeorusingpyside. if__name__=='__main__': importsys if(sys.flags.interactive!=1)ornothasattr(QtCore,'PYQT_VERSION'): QtGui.QApplication.instance().exec_()
知识补充:python图形化实例分享--pyqt5与pyqtgraph嵌入绘图
序言
之前也写过一些图形化界面的程序,基本上都是用wxPython写的,确实简单粗暴易上手。这次的任务是要写一个绘图的程序,wx模块就显得不太友好了,我就去网上找了一些资料,发现PyQtGraph画这种K线图、波形图等图形真是太简单了,更多的关于wx、qt等模块的细节学习可以看我后面的参考资料,我这里就分享一下我本程序的心得,和对有些方法使用上自己的理解
项目开始
引用头文件
pyqt5_draw_1这是主程序文件,负责主窗口图形化界面
importsys#与PyQt5配合使用 fromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QWidget,QGridLayout, QHBoxLayout,QVBoxLayout,QLabel,QComboBox,QPushButton, QDateEdit,QSpacerItem,QFrame,QSizePolicy,QSplitter, QRadioButton,QGroupBox,QCheckBox,QLineEdit,QAction) #上面是QT图形化要引用的所有包 fromPyQt5.QtCoreimportQt,QDate,QRect#对齐、时间等 fromPyQt5.QtCoreimportQThread,pyqtSignal#多线程管理 importpyqtgraphaspg#绘图包 fromTmp_Dataimport*#自定义文件,下面有介绍 fromMythreadingimport*#自定义文件,下面有介绍 frompyqt5_graphimport*#自定义文件,下面有介绍
如果PyQt5、pyqtgraph未安装的,最简单的安装方式就用python自带的pip工具安装,如果没有pip的或不会安装可直接百度
c:\>pipinstallPyQt5pyqtgraph
图形化主界面搭建
#pyqt5_draw_1.py文件名 importsys importcgitb fromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QWidget,QGridLayout, QHBoxLayout,QVBoxLayout,QLabel,QComboBox,QPushButton, QDateEdit,QSpacerItem,QFrame,QSizePolicy,QSplitter, QRadioButton,QGroupBox,QCheckBox,QLineEdit,QAction) fromPyQt5.QtCoreimportQt,QDate,QRect fromTmpDataimport* fromMythreadingimport* frompyqt5_graphimport* classQt_Test_Frame(QMainWindow): Items=[] def__init__(self): #super(Qt_Test_Frame,self).__init__(*args,**kw) super().__init__() #初始化界面 self._initUI() self.show() def_initUI(self): self.setWindowTitle("QT图形界面测试") self.resize(800,600) wwg=QWidget() #全局布局 wlayout=QVBoxLayout() h1_wlayout=QHBoxLayout() h2_wlayout=QHBoxLayout() h3_wlayout=QHBoxLayout() v4_wlayout=QVBoxLayout() v5_wlayout=QVBoxLayout() self.statusBar().showMessage("状态栏") #第一层 self._frist_story(h1_wlayout) #第二层 self._second_story(h2_wlayout) #第三层左 self._third_left(v4_wlayout,v5_wlayout) #第三层右 self._fouth_right(v5_wlayout) #加载 splt=self._my_line() splt2=self._my_line(False) wlayout.addSpacing(10)#增加布局间距 wlayout.addLayout(h1_wlayout) wlayout.addSpacing(10)#增加布局间距 wlayout.addLayout(h2_wlayout) wlayout.addSpacing(10)#增加布局间距 wlayout.addWidget(splt) wlayout.addLayout(h3_wlayout) wlayout.addWidget(self.statusBar()) h3_wlayout.addLayout(v4_wlayout,0) h3_wlayout.addWidget(splt2) h3_wlayout.addLayout(v5_wlayout,2) #wlayout.setAlignment(Qt.AlignTop) wwg.setLayout(wlayout) self.setCentralWidget(wwg) def_frist_story(self,h1_wlayout): #第一层布局 self.h1_combox1=QComboBox(minimumWidth=100) self.h1_combox1.addItems(wind_field) self.h1_combox2=QComboBox(minimumWidth=100) self.h1_combox2.addItems(wind_mach_chooice(self.h1_combox1.currentText())) self.h1_combox3=QComboBox(minimumWidth=100) self.h1_combox3.addItems(wind_blade) self.h1_combox4=QComboBox(minimumWidth=100) self.h1_combox4.addItems(signal_type) #行为测试暂时无法使用 h1_cb1_action=QAction("风场选择",self) h1_cb1_action.setStatusTip("请选择风场") self.h1_combox1.addAction(h1_cb1_action) h1_wlayout.addItem(QSpacerItem(20,20)) h1_wlayout.addWidget(QLabel("风场"),0) h1_wlayout.addWidget(self.h1_combox1,0) h1_wlayout.addItem(QSpacerItem(40,20)) h1_wlayout.addWidget(QLabel("风机"),0) h1_wlayout.addWidget(self.h1_combox2,0) h1_wlayout.addItem(QSpacerItem(40,20)) h1_wlayout.addWidget(QLabel("叶片ID"),0) h1_wlayout.addWidget(self.h1_combox3,0) h1_wlayout.addItem(QSpacerItem(40,20)) h1_wlayout.addWidget(QLabel("信号类型"),0) h1_wlayout.addWidget(self.h1_combox4,0) h1_wlayout.setAlignment(Qt.AlignLeft) #事件绑定 self.h1_combox1.currentIndexChanged.connect(self._wind_chooice) def_second_story(self,h2_wlayout): #第二层布局 self.h2_date1=QDateEdit(QDate.currentDate()) self.h2_date1.setCalendarPopup(True) self.h2_date2=QDateEdit(QDate.currentDate()) self.h2_date2.setCalendarPopup(True) self.h2_button=QPushButton("运行") self.h2_button2=QPushButton("停止") h2_wlayout.addItem(QSpacerItem(20,20)) h2_wlayout.addWidget(QLabel("起始"),0) h2_wlayout.addWidget(self.h2_date1) h2_wlayout.addItem(QSpacerItem(50,20)) h2_wlayout.addWidget(QLabel("结束"),0) h2_wlayout.addWidget(self.h2_date2) h2_wlayout.addItem(QSpacerItem(70,20)) h2_wlayout.addWidget(self.h2_button) h2_wlayout.addWidget(self.h2_button2) h2_wlayout.setAlignment(Qt.AlignLeft) #事件绑定 self.h2_button.clicked.connect(lambda:self._start_func()) self.h2_button2.clicked.connect(lambda:self._stop_func()) def_third_left(self,v4_wlayout,v5_wlayout): #第三层布局 #分量布局 v4_group_imf=QGridLayout() vbox1=QGroupBox("分量值") self.radio_1=QRadioButton("分量1") self.radio_2=QRadioButton("分量2") self.radio_3=QRadioButton("分量3") self.radio_4=QRadioButton("分量4") self.radio_5=QRadioButton("分量5") self.radio_6=QRadioButton("分量6") self.radio_7=QRadioButton("分量7") self.radio_8=QRadioButton("分量8") self.radio_9=QRadioButton("分量9") self.radio_1.setChecked(True) self.radio_val=self.radio_1.text() #优先级布局 v4_group_prior=QGridLayout() vbox2=QGroupBox("优先级") cb1=QCheckBox("叶片1") cb2=QCheckBox("叶片2") cb3=QCheckBox("叶片3") self.v4_lineEdit=QLineEdit() #时间布局 v4_group_time=QGridLayout() vbox3=QGroupBox("时间选择") self.v4_combox1=QComboBox(minimumWidth=100) self.v4_combox1.addItem("空") #按键 v4_button=QPushButton("显示图形") #写入网格格布局 v4_group_imf.addWidget(self.radio_1,0,0) v4_group_imf.addWidget(self.radio_2,0,1) v4_group_imf.addWidget(self.radio_3,1,0) v4_group_imf.addWidget(self.radio_4,1,1) v4_group_imf.addWidget(self.radio_5,2,0) v4_group_imf.addWidget(self.radio_6,2,1) v4_group_imf.addWidget(self.radio_7,3,0) v4_group_imf.addWidget(self.radio_8,3,1) v4_group_imf.addWidget(self.radio_9,4,0) v4_group_prior.addWidget(cb1,1,0) v4_group_prior.addWidget(cb2,2,0) v4_group_prior.addWidget(cb3,3,0) v4_group_prior.addWidget(QLabel("选择是:"),4,0) v4_group_prior.addWidget(self.v4_lineEdit,5,0) v4_group_time.addWidget(self.v4_combox1) #写入左侧布局 vbox1.setLayout(v4_group_imf) vbox2.setLayout(v4_group_prior) vbox3.setLayout(v4_group_time) v4_wlayout.addItem(QSpacerItem(50,20)) v4_wlayout.addWidget(vbox1) v4_wlayout.addItem(QSpacerItem(50,20)) v4_wlayout.addWidget(vbox2) v4_wlayout.addItem(QSpacerItem(50,20)) v4_wlayout.addWidget(vbox3) v4_wlayout.addItem(QSpacerItem(50,20)) v4_wlayout.addWidget(v4_button) v4_wlayout.addItem(QSpacerItem(50,20)) #事件绑定 self.radio_1.toggled.connect(lambda:self._changestyle(self.radio_1)) self.radio_2.toggled.connect(lambda:self._changestyle(self.radio_2)) self.radio_3.toggled.connect(lambda:self._changestyle(self.radio_3)) self.radio_4.toggled.connect(lambda:self._changestyle(self.radio_4)) self.radio_5.toggled.connect(lambda:self._changestyle(self.radio_5)) self.radio_6.toggled.connect(lambda:self._changestyle(self.radio_6)) self.radio_7.toggled.connect(lambda:self._changestyle(self.radio_7)) self.radio_8.toggled.connect(lambda:self._changestyle(self.radio_8)) self.radio_9.toggled.connect(lambda:self._changestyle(self.radio_9)) cb1.stateChanged.connect(lambda:self._prior_func(cb1)) cb2.stateChanged.connect(lambda:self._prior_func(cb2)) cb3.stateChanged.connect(lambda:self._prior_func(cb3)) v4_button.clicked.connect(lambda:self._show_func(v5_wlayout)) def_fouth_right(self,v5_wlayout): #加载波形图 self.tmp_plt=plt_init() v5_wlayout.addWidget(self.tmp_plt) def_my_line(self,var=True): #var为True时,为横线,否则为竖线 line=QFrame(self) line_var=QFrame.HLine sp_var=Qt.Horizontal ifnotvar: line_var=QFrame.VLine sp_var=Qt.Vertical line.setFrameShape(line_var) line.setFrameShadow(QFrame.Sunken) splitter=QSplitter(sp_var) splitter.addWidget(line) returnsplitter def_wind_chooice(self): tmp_list=wind_mach_chooice(self.h1_combox1.currentText()) self.h1_combox2.clear() self.h1_combox2.addItems(tmp_list) def_start_func(self): a=self.h1_combox1.currentText() b=self.h1_combox2.currentText() c=self.h1_combox3.currentText() d=self.h1_combox4.currentText() e=self.h2_date1.dateTime().toString("yy-MM-dd") f=self.h2_date2.dateTime().toString("yy-MM-dd") #多线程的引用 self.start_func=RunThread(target=self._start_thread,args=(a,b,c,d,e,f)) #多线程启动 self.start_func.start() def_stop_func(self): #线程停止 self.start_func.stop() print("运行结束") def_start_thread(self,a,b,c,d,e,f): print("*****运行打印*****") print(wind_mach_chooice(a)) print(a,b,c,d) print(e) print(f) print("%s"%(time.strftime('<%H:%M:%S>',time.localtime()))) self.v4_combox1.clear() self.v4_combox1.addItems(tmp_time_list) print("*****运行打印*****") def_changestyle(self,btn): #单选项的判断函数 ifbtn.isChecked(): self.radio_val=btn.text() #print("%s"%(time.strftime('<%H:%M:%S>',time.localtime()))) def_prior_func(self,cb): #复选框内容添加 ifcb.isChecked(): ifcb.text()[-1]notinself.Items: self.Items.append(cb.text()[-1]) shop_cart=",".join(self.Items) self.v4_lineEdit.setText(shop_cart) else: ifcb.text()[-1]inself.Items: self.Items.remove(cb.text()[-1]) shop_cart=",".join(self.Items) self.v4_lineEdit.setText(shop_cart) def_show_func(self,v5_wlayout): print("*****显示打印*****") print(self.radio_val) num=self.v4_lineEdit.text() print(self.v4_combox1.currentText()) v5_wlayout.removeWidget(self.tmp_plt) self.tmp_plt=plt_show(num) v5_wlayout.addWidget(self.tmp_plt) print("*****显示打印*****") if__name__=='__main__': cgitb.enable(format="text") app=QApplication(sys.argv) win=Qt_Test_Frame() sys.exit(app.exec_())
处理把列表文件转成字典与绘图
#pyqt5_graph.py文件名 importpyqtgraphaspg fromTmpDataimport_read_data,wind_mach_chooice colour=["r","g","b"] yp_list=["叶片1","叶片2","叶片3"] def_data_to_dict(): mydict={} formy_vars,iinzip(_read_data(),range(len(_read_data()))): tmp_dict={} forvar,jinzip(my_vars,range(len(my_vars))): tmp_dict[var[0]]=var[1] mydict[i]=tmp_dict returnmydict defplt_init(): #绘图初始化 pg.setConfigOption("background","w") plt=pg.PlotWidget() plt.addLegend(size=(150,80)) plt.showGrid(x=True,y=True,alpha=0.5) returnplt defplt_show(num): #传绘制的新图 mydict=_data_to_dict() pg.setConfigOption("background","w") plt=pg.PlotWidget() plt.addLegend(size=(150,80)) plt.showGrid(x=True,y=True,alpha=0.5) foriinnum.split(","): i=int(i)-1 plt.plot(x=list(mydict[i].keys()),y=list(mydict[i].values()),pen=colour[i], name=yp_list[i]) returnplt if__name__=='__main__': _data_to_dict() pass
模拟给其它文件传指定数据
#TmpData.py文件名 importos importnumpyasnp file_path=os.path.join(os.getcwd(),"风机采集信号数据\\") wind_field=["风场1","风场2","风场3"] wind_machine={"风场1":["大别山","天目山"], "风场2":["昆仑山","三清山"], "风场3":["五指山","火焰山"]} wind_blade=["X-20Hz","X-1K","Y-20Hz","Y-1K"] signal_type=["包络","振动"] tmp_time_list=["20190501","20190502","20190504","20190508","20190515"] defwind_mach_chooice(val): returnwind_machine[val] def_read_data(): file_list=os.listdir(file_path) file_list=[varforvarinfile_listifvar.split(".")[1]=="csv"] a=[] forvarinfile_list: tmp=os.path.join(file_path,var) rd_file=np.loadtxt(tmp,delimiter=",",usecols=(0,1)) a.append(rd_file) returna[0],a[1],a[2]
多线程管理
因为程序运行时间久,主界面就会出现假死的状态,要引用多线程
#Mythreading.py文件名 fromPyQt5.QtCoreimportQThread,pyqtSignal classRunThread(QThread): counter_value=pyqtSignal(int) def__init__(self,target,args,name=""): QThread.__init__(self) self.target=target self.args=args self.is_running=True defrun(self): #print("starting",self.name,"at:",ctime()) self.res=self.target(*self.args) defstop(self): #负责停止线程 self.terminate()
关于QT异常直接退出没有报错的情况,查bug比较麻烦
importcgitb #这句放在所有程序开始前,这样就可以正常打印异常了 cgitb.enable(format="text")
这些天本人身体不舒服,但还是把做完的这个分享出来,有些细节没有具体说明,下次身体好点,再单独拿出来分享,累了,晚安!
以上这篇Python3.x+pyqtgraph实现数据可视化教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。