CPU plot demo — PythonQwt 0.14 Manual (original) (raw)
import os
import numpy as np from qtpy.QtCore import QRectF, Qt, QTime from qtpy.QtGui import QBrush, QColor from qtpy.QtWidgets import QLabel, QVBoxLayout, QWidget
from qwt import ( QwtLegend, QwtLegendData, QwtPlot, QwtPlotCurve, QwtPlotItem, QwtPlotMarker, QwtScaleDraw, QwtText, ) from qwt.tests import utils
class CpuStat: User = 0 Nice = 1 System = 2 Idle = 3 counter = 0 dummyValues = ( (103726, 0, 23484, 819556), (103783, 0, 23489, 819604), (103798, 0, 23490, 819688), (103820, 0, 23490, 819766), (103840, 0, 23493, 819843), (103875, 0, 23499, 819902), (103917, 0, 23504, 819955), (103950, 0, 23508, 820018), (103987, 0, 23510, 820079), (104020, 0, 23513, 820143), (104058, 0, 23514, 820204), (104099, 0, 23520, 820257), (104121, 0, 23525, 820330), (104159, 0, 23530, 820387), (104176, 0, 23534, 820466), (104215, 0, 23538, 820523), (104245, 0, 23541, 820590), (104267, 0, 23545, 820664), (104311, 0, 23555, 820710), (104355, 0, 23565, 820756), (104367, 0, 23567, 820842), (104383, 0, 23572, 820921), (104396, 0, 23577, 821003), (104413, 0, 23579, 821084), (104446, 0, 23588, 821142), (104521, 0, 23594, 821161), (104611, 0, 23604, 821161), (104708, 0, 23607, 821161), (104804, 0, 23611, 821161), (104895, 0, 23620, 821161), (104993, 0, 23622, 821161), (105089, 0, 23626, 821161), (105185, 0, 23630, 821161), (105281, 0, 23634, 821161), (105379, 0, 23636, 821161), (105472, 0, 23643, 821161), (105569, 0, 23646, 821161), (105666, 0, 23649, 821161), (105763, 0, 23652, 821161), (105828, 0, 23661, 821187), (105904, 0, 23666, 821206), (105999, 0, 23671, 821206), (106094, 0, 23676, 821206), (106184, 0, 23686, 821206), (106273, 0, 23692, 821211), (106306, 0, 23700, 821270), (106341, 0, 23703, 821332), (106392, 0, 23709, 821375), (106423, 0, 23715, 821438), (106472, 0, 23721, 821483), (106531, 0, 23727, 821517), (106562, 0, 23732, 821582), (106597, 0, 23736, 821643), (106633, 0, 23737, 821706), (106666, 0, 23742, 821768), (106697, 0, 23744, 821835), (106730, 0, 23748, 821898), (106765, 0, 23751, 821960), (106799, 0, 23754, 822023), (106831, 0, 23758, 822087), (106862, 0, 23761, 822153), (106899, 0, 23763, 822214), (106932, 0, 23766, 822278), (106965, 0, 23768, 822343), (107009, 0, 23771, 822396), (107040, 0, 23775, 822461), (107092, 0, 23780, 822504), (107143, 0, 23787, 822546), (107200, 0, 23795, 822581), (107250, 0, 23803, 822623), (107277, 0, 23810, 822689), (107286, 0, 23810, 822780), (107313, 0, 23817, 822846), (107325, 0, 23818, 822933), (107332, 0, 23818, 823026), (107344, 0, 23821, 823111), (107357, 0, 23821, 823198), (107368, 0, 23823, 823284), (107375, 0, 23824, 823377), (107386, 0, 23825, 823465), (107396, 0, 23826, 823554), (107422, 0, 23830, 823624), (107434, 0, 23831, 823711), (107456, 0, 23835, 823785), (107468, 0, 23838, 823870), (107487, 0, 23840, 823949), (107515, 0, 23843, 824018), (107528, 0, 23846, 824102), (107535, 0, 23851, 824190), (107548, 0, 23853, 824275), (107562, 0, 23857, 824357), (107656, 0, 23863, 824357), (107751, 0, 23868, 824357), (107849, 0, 23870, 824357), (107944, 0, 23875, 824357), (108043, 0, 23876, 824357), (108137, 0, 23882, 824357), (108230, 0, 23889, 824357), (108317, 0, 23902, 824357), (108412, 0, 23907, 824357), (108511, 0, 23908, 824357), (108608, 0, 23911, 824357), (108704, 0, 23915, 824357), (108801, 0, 23918, 824357), (108891, 0, 23928, 824357), (108987, 0, 23932, 824357), (109072, 0, 23943, 824361), (109079, 0, 23943, 824454), (109086, 0, 23944, 824546), (109098, 0, 23950, 824628), (109108, 0, 23955, 824713), (109115, 0, 23957, 824804), (109122, 0, 23958, 824896), (109132, 0, 23959, 824985), (109142, 0, 23961, 825073), (109146, 0, 23962, 825168), (109153, 0, 23964, 825259), (109162, 0, 23966, 825348), (109168, 0, 23969, 825439), (109176, 0, 23971, 825529), (109185, 0, 23974, 825617), (109193, 0, 23977, 825706), (109198, 0, 23978, 825800), (109206, 0, 23978, 825892), (109212, 0, 23981, 825983), (109219, 0, 23981, 826076), (109225, 0, 23981, 826170), (109232, 0, 23984, 826260), (109242, 0, 23984, 826350), (109255, 0, 23986, 826435), (109268, 0, 23987, 826521), (109283, 0, 23990, 826603), (109288, 0, 23991, 826697), (109295, 0, 23993, 826788), (109308, 0, 23994, 826874), (109322, 0, 24009, 826945), (109328, 0, 24011, 827037), (109338, 0, 24012, 827126), (109347, 0, 24012, 827217), (109354, 0, 24017, 827305), (109367, 0, 24017, 827392), (109371, 0, 24019, 827486), )
def __init__(self):
self.procValues = self.__lookup()
def statistic(self):
values = self.__lookup()
userDelta = 0.0
for i in [CpuStat.User, CpuStat.Nice]:
userDelta += values[i] - self.procValues[i]
systemDelta = values[CpuStat.System] - self.procValues[CpuStat.System]
totalDelta = 0.0
for i in range(len(self.procValues)):
totalDelta += values[i] - self.procValues[i]
self.procValues = values
return 100.0 * userDelta / totalDelta, 100.0 * systemDelta / totalDelta
def upTime(self):
result = QTime()
for item in self.procValues:
result = result.addSecs(int(0.01 * item))
return result
def __lookup(self):
if os.path.exists("/proc/stat"):
with open("/proc/stat") as file:
for line in file:
words = line.split()
if words[0] == "cpu" and len(words) >= 5:
return [float(w) for w in words[1:]]
else:
result = CpuStat.dummyValues[CpuStat.counter]
CpuStat.counter += 1
CpuStat.counter %= len(CpuStat.dummyValues)
return result
class CpuPieMarker(QwtPlotMarker): def init(self, *args): QwtPlotMarker.init(self, *args) self.setZ(1000.0) self.setRenderHint(QwtPlotItem.RenderAntialiased, True)
def rtti(self):
return QwtPlotItem.Rtti_PlotUserItem
def draw(self, painter, xMap, yMap, rect):
margin = 5
pieRect = QRectF()
pieRect.setX(rect.x() + margin)
pieRect.setY(rect.y() + margin)
pieRect.setHeight(int(yMap.transform(80.0)))
pieRect.setWidth(pieRect.height())
angle = 3 * 5760 / 4
for key in ["User", "System", "Idle"]:
curve = self.plot().cpuPlotCurve(key)
if curve.dataSize():
value = int(5760 * curve.sample(0).y() / 100.0)
painter.save()
painter.setBrush(QBrush(curve.pen().color(), Qt.SolidPattern))
painter.drawPie(pieRect, int(-angle), int(-value))
painter.restore()
angle += value
class TimeScaleDraw(QwtScaleDraw): def init(self, baseTime, *args): QwtScaleDraw.init(self, *args) self.baseTime = baseTime
def label(self, value):
upTime = self.baseTime.addSecs(int(value))
return QwtText(upTime.toString())
class Background(QwtPlotItem): def init(self): QwtPlotItem.init(self) self.setZ(0.0)
def rtti(self):
return QwtPlotItem.Rtti_PlotUserItem
def draw(self, painter, xMap, yMap, rect):
c = QColor(Qt.white)
r = QRectF(rect)
for i in range(100, 0, -10):
r.setBottom(int(yMap.transform(i - 10)))
r.setTop(int(yMap.transform(i)))
painter.fillRect(r, c)
c = c.darker(110)
class CpuCurve(QwtPlotCurve): def init(self, *args): QwtPlotCurve.init(self, *args) self.setRenderHint(QwtPlotItem.RenderAntialiased)
def setColor(self, color):
c = QColor(color)
c.setAlpha(150)
self.setPen(c)
self.setBrush(c)
class CpuPlot(QwtPlot): HISTORY = 60
def __init__(self, unattended=False):
QwtPlot.__init__(self)
self.curves = {}
self.data = {}
self.timeData = 1.0 * np.arange(self.HISTORY - 1, -1, -1)
self.cpuStat = CpuStat()
self.setAutoReplot(False)
self.plotLayout().setAlignCanvasToScales(True)
legend = QwtLegend()
legend.setDefaultItemMode(QwtLegendData.Checkable)
self.insertLegend(legend, QwtPlot.RightLegend)
self.setAxisTitle(QwtPlot.xBottom, "System Uptime [h:m:s]")
self.setAxisScaleDraw(QwtPlot.xBottom, TimeScaleDraw(self.cpuStat.upTime()))
self.setAxisScale(QwtPlot.xBottom, 0, self.HISTORY)
self.setAxisLabelRotation(QwtPlot.xBottom, -50.0)
self.setAxisLabelAlignment(QwtPlot.xBottom, Qt.AlignLeft | Qt.AlignBottom)
self.setAxisTitle(QwtPlot.yLeft, "Cpu Usage [%]")
self.setAxisScale(QwtPlot.yLeft, 0, 100)
background = Background()
background.attach(self)
pie = CpuPieMarker()
pie.attach(self)
curve = CpuCurve("System")
curve.setColor(Qt.red)
curve.attach(self)
self.curves["System"] = curve
self.data["System"] = np.zeros(self.HISTORY, float)
curve = CpuCurve("User")
curve.setColor(Qt.blue)
curve.setZ(curve.z() - 1.0)
curve.attach(self)
self.curves["User"] = curve
self.data["User"] = np.zeros(self.HISTORY, float)
curve = CpuCurve("Total")
curve.setColor(Qt.black)
curve.setZ(curve.z() - 2.0)
curve.attach(self)
self.curves["Total"] = curve
self.data["Total"] = np.zeros(self.HISTORY, float)
curve = CpuCurve("Idle")
curve.setColor(Qt.darkCyan)
curve.setZ(curve.z() - 3.0)
curve.attach(self)
self.curves["Idle"] = curve
self.data["Idle"] = np.zeros(self.HISTORY, float)
self.showCurve(self.curves["System"], True)
self.showCurve(self.curves["User"], True)
self.showCurve(self.curves["Total"], False or unattended)
self.showCurve(self.curves["Idle"], False or unattended)
self.startTimer(20 if unattended else 1000)
legend.checked.connect(self.showCurve)
self.replot()
def timerEvent(self, e):
for data in self.data.values():
data[1:] = data[0:-1]
self.data["User"][0], self.data["System"][0] = self.cpuStat.statistic()
self.data["Total"][0] = self.data["User"][0] + self.data["System"][0]
self.data["Idle"][0] = 100.0 - self.data["Total"][0]
self.timeData += 1.0
self.setAxisScale(QwtPlot.xBottom, self.timeData[-1], self.timeData[0])
for key in self.curves.keys():
self.curves[key].setData(self.timeData, self.data[key])
self.replot()
def showCurve(self, item, on, index=None):
item.setVisible(on)
self.legend().legendWidget(item).setChecked(on)
self.replot()
def cpuPlotCurve(self, key):
return self.curves[key]
class CpuDemo(QWidget): def init(self, parent=None, unattended=False): super(CpuDemo, self).init(parent) layout = QVBoxLayout() self.setLayout(layout) plot = CpuPlot(unattended=unattended) plot.setTitle("History") layout.addWidget(plot) label = QLabel("Press the legend to en/disable a curve") layout.addWidget(label)
def test_cpudemo(): """CPU demo""" utils.test_widget(CpuDemo, (600, 400))
if name == "main": test_cpudemo()