Grafik Çizdirme

Bir veri kaynağından sürekli akan sayıları canlı grafik olarak gösterecek bir uygulama yazacağız.

Basitlik açısından, tek pencere ile çalışacağız. Birden fazla kaynağın verilerini istediğimiz zaman aralıklarında örnekleyen ve bu bilgiyi görselleştiren bir uygulama yazacağız.

Uygulamaya geçmeden önce kurmanız gereken ek modüller:

  • psutil : İşletim sisteminden bağımsız performans metrikleri sağlar.

  • pyqtgraph : Çizim kütüphanemiz.

Designer içinde tasarım yaparken, pyqtgraph nesnesi yerleştirebilmek mümkündür. Aşağıdaki bilgi, pyqtgraph belgesinden türkçeye çevirilmiştir:

pyqtgraph PySide2 destegi

Pyqtgraph kütüphanesinin PySide2 desteği henüz geliştirilme aşamasındadır. Stabil sürümü çıktığında bu belge de ona göre güncellenecektir.

PyQt Uygulamasının içine pyqtgraph nesneleri yerleştirme

Pyqtgraph kütüphanesi tarafından sağlanan nesneleri, designer uygulaması içinde herhangi bir Qt nesnesi gibi yerleştirebilmek mümkündür. PlotWidget, ImageView, GraphicsLayoutWidget ve GraphicsView nesneleri en önemli olanlarıdır. Bu nesneler, designer içinde ‘Promote To…’ özelliği ile ui dosyasının içine eklenirler. Bu işlem için:

  1. Designer’da pencerenize QGraphicsView nesnesi yerleştirin.

  2. Bu nesneye fare sağ tuşu ile tıklayıp, ‘Promote To…’ seçin.

  3. ‘Promoted class name’ kısmında, kullanmak istediğiniz pyqtgraph nesnesinin adını yazın. (PlotWidget, GraphicsLayoutWidget gibi)

  4. ‘Header file’ kısmına ‘pyqtgraph’ yazın.

  5. ‘Add’ butonuna basın ve ardından ‘Promote’ butonuna basın.

Uygulamamıza bir combobox yerleştiriyoruz. İşlemci ve Ağ adında iki eleman ekleyip, her birinin comment alanına işlemci için 1, ağ için 2 yazıyoruz.

Yukarıda anlatıldığı gibi QGraphicsView ekleyip, PlotWidget’a çeviriyoruz. Pencere için oluşturulmuş diyalog’a da dlgGrafik adını verip kaydediyoruz.

../_images/pyqtgraph-plot-001.png

QGraphicsView nesnesinin pyqtgraph PlotWidget’a dönüştürülmesi.

../_images/pyqtgraph-plot-002.png

Combobox comment kısmı düzenleme

Promote işlemi sonrasında, uic ile üretilen python kodunun içine

from pyqtgraph import PlotWidget

satırının eklendiğini göreceksiniz.

psutils modülünü kullanarak çizilecek sayıları sağlayacak bir nesne hazırlayacağız.

../_images/pyqtgraph-plot-003.png

İşlemci Yükü, 0-100 aralığında

../_images/pyqtgraph-plot-004.png

Ağ trafiği, gelen byte

Veri Sinifi

import psutil

class Veri:
    def __init__(self, aralik=1, maxnokta = 50, artan=False):
        self.noktalar = []
        self.aralik = aralik
        self.maxnokta = maxnokta
        self.artan = artan
        self.sonsayi = 0
        
    def sayi_ekle(self, sayi):
        if len(self.noktalar) >= self.maxnokta:
            self.noktalar = self.noktalar[1:]
        if self.artan is False:
            self.noktalar.append(sayi)
        else:
            if len(self.noktalar) == 0:
                self.sonsayi = sayi
                self.noktalar = [0]
            else:

                self.noktalar.append(sayi  - self.sonsayi)
                self.sonsayi = sayi
                
class Islemci(Veri):
    def __init__(self):
        Veri.__init__(self)

    def ekle(self):
        self.sayi_ekle(psutil.cpu_percent())

class Ag(Veri):
    def __init__(self):
        Veri.__init__(self, artan=True)

    def ekle(self):
        # net_io_counters()[1], bytes received veriyor
        self.sayi_ekle(psutil.net_io_counters()[1])
        
if __name__ == "__main__":
    ag = Ag()
    import time
    for i in range(500):
        ag.ekle()
        print( ag.noktalar)
        time.sleep(2)

Ana Uygulama

#from PySide.QtGui import *
#from PySide.QtCore import *

from PySide2.QtWidgets import QDialog, QApplication
from PySide2.QtCore import QThread, Signal

from ui2_grafik import Ui_dlgGrafik

from veri import Ag, Islemci
import time
import sys
        

class VeriKaynagi(QThread):
    updateProgress = Signal()
    
    def __init__(self):
        QThread.__init__(self)
        self.kaynaklar = {0: Islemci(), 1: Ag()}

    def veri(self, id):
        return self.kaynaklar[id].noktalar
        
    def run(self):
        while 1:
            for kaynak in self.kaynaklar.values():
                kaynak.ekle()
            self.updateProgress.emit()
            time.sleep(1)

class MainWindow(QDialog, Ui_dlgGrafik):
    def __init__(self, app = None):
        super(MainWindow, self).__init__()
        self.app = app
        self.setupUi(self)
        self.kaynak = VeriKaynagi()
        self.kaynak.start()
        self.kaynak.updateProgress.connect(self.ciz)
        self.secili = 0
        self.show()

        
    def degistir(self):
        if self.cmbKaynak.currentIndex() != self.secili:
            self.plotGrafik.clear()
            self.secili = self.cmbKaynak.currentIndex()
            self.plotGrafik.plot(self.kaynak[self.secili].noktalar)
        
    def ciz(self):
        sayilar = self.kaynak.veri(self.secili)
        if len(sayilar) == self.kaynak.kaynaklar[self.secili].maxnokta:
            self.plotGrafik.clear()
        self.plotGrafik.plot(sayilar)
            
if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWin = MainWindow(app)
    ret = app.exec_()
    app.exit()
    sys.exit(ret)