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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。