chart控件做实时曲线显示_用PyQt5.QtChart实现动态曲线图
生活随笔
收集整理的這篇文章主要介紹了
chart控件做实时曲线显示_用PyQt5.QtChart实现动态曲线图
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
之前一直用爬蟲(chóng)捉取路由實(shí)時(shí)上下載的記錄用數(shù)據(jù)庫(kù)保存,有時(shí)可用matplotlib來(lái)查看時(shí)間與上下傳的曲線圖,但是靜態(tài)的,查詢的時(shí)間段需自行認(rèn)定,雖然qt的日歷類可以比較方便取日期按日期查,但總覺(jué)要點(diǎn)有點(diǎn)麻煩,又不想看24小時(shí)的數(shù)據(jù),截取最近幾小時(shí)觀看數(shù)據(jù)并實(shí)時(shí)展示應(yīng)該是很好的方式,經(jīng)百度發(fā)現(xiàn)pyqt有個(gè)很方便的庫(kù)來(lái)展示動(dòng)態(tài)數(shù)據(jù),這個(gè)庫(kù)是pyqtchart,安裝PyQt時(shí)并沒(méi)有這個(gè)庫(kù)的,需另行安裝,pip install pyqtchart安裝就可以了,下面就結(jié)合代碼和實(shí)際情況記錄一下。
import sqlite3,sys,time from datetime import datetime from PyQt5.QtChart import QDateTimeAxis,QValueAxis,QSplineSeries,QChart,QChartView from PyQt5.QtWidgets import QApplication from PyQt5.QtGui import QPainter from PyQt5.QtCore import QDateTime,Qt,QTimerclass ChartView(QChartView,QChart): #原代碼如此,繼承了兩個(gè)類,其實(shí)去掉QChart也沒(méi)影響def __init__(self, *args, **kwargs):super(ChartView, self).__init__(*args, **kwargs)self.connect = sqlite3.connect("netdata.db") #數(shù)據(jù)庫(kù),表名為t1,包括時(shí)間(年月日時(shí)分秒的方式,用sqlite的自動(dòng)時(shí)間截生成的,為方便自己看,轉(zhuǎn)成年月日,結(jié)果是個(gè)坑),下載速度,上傳速度self.resize(1500, 500)self.setRenderHint(QPainter.Antialiasing) # 抗鋸齒,注釋此行曲線很難看self.limitminute=240 #設(shè)置顯示多少分鐘內(nèi)的活動(dòng)self.maxspeed = 300 #預(yù)設(shè)y軸最大值self.chart_init()self.timer_init()def timer_init(self):#使用QTimer,2秒觸發(fā)一次,更新數(shù)據(jù)self.timer = QTimer(self)self.timer.timeout.connect(self.drawLine)self.timer.start(2000)def chart_init(self):self.chart = QChart()self.series = QSplineSeries() #這個(gè)是平滑曲線類,而QSplineSeries()是折線類,根所自己需求選用,下載數(shù)據(jù)曲線self.series_upload = QSplineSeries() #上傳數(shù)據(jù)曲線#設(shè)置曲線名稱self.series.setName("下載速度")self.series_upload.setName('上傳速度')#把曲線添加到QChart的實(shí)例中self.chart.addSeries(self.series)self.chart.addSeries(self.series_upload)#聲明并初始化X軸,Y軸self.dtaxisX = QDateTimeAxis()self.vlaxisY = QValueAxis()#設(shè)置坐標(biāo)軸顯示范圍self.dtaxisX.setMin(QDateTime.currentDateTime().addSecs(-self.limitminute*60))self.dtaxisX.setMax(QDateTime.currentDateTime().addSecs(0))self.vlaxisY.setMin(0) self.vlaxisY.setMax(self.maxspeed) #設(shè)置y軸最大值#設(shè)置X軸時(shí)間樣式self.dtaxisX.setFormat("hh:mm") #關(guān)注就是幾小時(shí)內(nèi)的數(shù)據(jù),就留時(shí)分好了#設(shè)置坐標(biāo)軸上的格點(diǎn)self.dtaxisX.setTickCount(15) #平均分的刻度分隔self.vlaxisY.setTickCount(10)#設(shè)置坐標(biāo)軸名稱self.dtaxisX.setTitleText("時(shí)間")self.vlaxisY.setTitleText("速度(M)")#設(shè)置網(wǎng)格顯示,并設(shè)為灰色 self.vlaxisY.setGridLineVisible(True)self.vlaxisY.setGridLineColor(Qt.gray)self.dtaxisX.setGridLineVisible(True)self.dtaxisX.setGridLineColor(Qt.gray)#把坐標(biāo)軸添加到chart中self.chart.addAxis(self.dtaxisX,Qt.AlignBottom)self.chart.addAxis(self.vlaxisY,Qt.AlignLeft)#把曲線關(guān)聯(lián)到坐標(biāo)軸self.series.attachAxis(self.dtaxisX)self.series.attachAxis(self.vlaxisY)self.series_upload.attachAxis(self.dtaxisX)self.series_upload.attachAxis(self.vlaxisY)self.setChart(self.chart)def drawLine(self):#獲取當(dāng)前時(shí)間bjtime = QDateTime.currentDateTime()#更新X軸坐標(biāo)self.dtaxisX.setMin(bjtime.addSecs(-self.limitminute*60))self.dtaxisX.setMax(bjtime.addSecs(0))#設(shè)Y軸最大值,查詢數(shù)據(jù)庫(kù)最近4小時(shí)內(nèi)的下載最大值,并乘1.2作為y軸最大值for xx in self.connect.execute("select max(downdata) from t1 where time > datetime('now','-4 hour','localtime') order by time"):if xx:self.vlaxisY.setMax(int(xx[0] * 1.2))else:self.vlaxisY.setMax(self.maxspeed)if self.series.at(0): #self.serie存在索引0時(shí),也就是起碼有一個(gè)數(shù)據(jù)對(duì)過(guò)舊數(shù)據(jù)進(jìn)行清除,self.series.removePoints兩參數(shù)一個(gè)是索引,一個(gè)是從索引起始刪除多少個(gè)數(shù)值,兩條數(shù)據(jù)均如此處理if self.series.at(0).x()<bjtime.addSecs(-self.limitminute*60).toMSecsSinceEpoch(): #self.series.at(0).x()其實(shí)就是圖像x坐標(biāo)值,與原始數(shù)據(jù)可能并不完全相等,小數(shù)點(diǎn)后的值是約去了的,bjtime的toMSecsSinceEpoch()其實(shí)與time.time()相約,不過(guò)前者是整數(shù),是后者的1000倍,所以后面需要轉(zhuǎn)換self.series.removePoints(0, 1)if self.series_upload.at(0):if self.series_upload.at(0).x()<bjtime.addSecs(-self.limitminute*60).toMSecsSinceEpoch():self.series_upload.removePoints(0, 1)for xx in self.connect.execute("select * from t1 order by time desc limit 1"):#x1 = self.connect.execute("select strftime('%s',?)", (xx[0],)).fetchone()[0] #用此法轉(zhuǎn)出來(lái)的時(shí)間截與time.time()整好差8個(gè)時(shí)區(qū),用sqlite不知如何處理了x1=time.mktime(datetime.strptime(xx[0], '%Y-%m-%d %H:%M:%S').timetuple()) #用py內(nèi)置庫(kù)的辦法有日期轉(zhuǎn)為時(shí)間截x_time=int(x1)*1000 #再乘1000,以符號(hào)格式要求y0_value=xx[1] #取得下載數(shù)據(jù)y1_value=xx[2] #取得上傳數(shù)據(jù)#添加數(shù)據(jù)到曲線末端if self.series.at(0): #因數(shù)據(jù)庫(kù)并非每秒更新,為免相同數(shù)據(jù)重復(fù)錄入,先判斷self.series起碼有一個(gè)數(shù)據(jù)if x_time!=self.series.at(self.series.count()-1).x(): #假如最新的時(shí)間軸與數(shù)據(jù)庫(kù)取得的不一致就錄入,相同就跳過(guò)self.series.append(x_time, y0_value)else: #當(dāng)self.series為空時(shí)起碼錄入第一個(gè)數(shù)據(jù),下面另外一軸同樣處理self.series.append(x_time,y0_value)if self.series_upload.at(0):if x_time!=self.series_upload.at(self.series_upload.count()-1).x():self.series_upload.append(x_time, y1_value)else:self.series_upload.append(x_time,y1_value)#print(self.series.count(),self.series_upload.count())if __name__ == "__main__":app = QApplication(sys.argv)view = ChartView()view.show()sys.exit(app.exec_())下面上張效果圖
不過(guò)這個(gè)標(biāo)題到底是怎么改的?沒(méi)找到什么方法
總結(jié)
以上是生活随笔為你收集整理的chart控件做实时曲线显示_用PyQt5.QtChart实现动态曲线图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: div自动滚动_实现图片自动和手动切换的
- 下一篇: python两数交换 函数_Python