import sys
import random
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QSizePolicy, QWidget
from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import psutil as p
def cpu_usage():
t = p.cpu_times()
return [t.user, t.system, t.idle]
before = cpu_usage()
def get_cpu_usage():
global before
now = cpu_usage()
delta = [now[i] - before[i] for i in range(len(now))]
total = sum(delta)
before = now
return [(100.0*dt)/(total+0.1) for dt in delta]
POINTS = 300
user = [None] * POINTS
# 执行内核进程和中断的时间百分比
sys2 = [None] * POINTS
# CPU处于空闲状态的时间百分比
idle = [None] * POINTS
class MyMplCanvas(FigureCanvas):
"""FigureCanvas的最终的父类其实是QWidget。"""
def __init__(self, parent=None, width=10, height=8, dpi=100):
# 配置中文显示
plt.rcParams['font.family'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
self.fig = Figure(figsize=(width, height),dpi=dpi) # 新建一个figure
self.axes = self.fig.add_subplot(111) # 建立一个子图,如果要建立复合图,可以在这里修改
#self.fig, self.axes = plt.subplots()#不知道为何matplotlib在backend模式下必须用上两行来执行,用本行会报
#'Process finished with exit code -1073741819 (0xC0000005)'
self.axes.set_ylim([0, 100])
self.axes.set_xlim([0, POINTS])
self.axes.set_autoscale_on(False)
self.axes.set_xticks([])
self.axes.set_yticks(range(0, 101, 10))
self.axes.grid(True)
self.l_user,= self.axes.plot(range(POINTS), user, label='User %')
self.l_sys,= self.axes.plot(range(POINTS),sys2, label='Sys %')
self.l_idle,= self.axes.plot(range(POINTS), idle, label='Idle %')
self.axes.legend(loc='upper center', ncol=6, prop=font_manager.FontProperties(size=20))
#self.bg = self.fig.canvas.copy_from_bbox(self.axes.bbox)
#self.fig.canvas.copy_from_bbox(self.axes.bbox)
FigureCanvas.__init__(self, self.fig)
self.setParent(parent)
'''定义FigureCanvas的尺寸策略,这部分的意思是设置FigureCanvas,使之尽可能的向外填充空间。'''
FigureCanvas.setSizePolicy(self,QSizePolicy.Expanding,QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
def start_static_plot(self):
self.fig.suptitle('测试静态图')
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
self.axes.set_ylabel('静态图:Y轴')
self.axes.set_xlabel('静态图:X轴')
self.axes.grid(True)
'''启动绘制动态图'''
def start_dynamic_plot(self, *args, **kwargs):
timer = QtCore.QTimer(self)
#timer.timeout.connect(self.update_figure) # 每隔一段时间就会触发一次update_figure函数。
timer.timeout.connect(self.OnTimer)
timer.start(500) # 触发的时间间隔为1秒。
'''动态图的绘图逻辑可以在这里修改'''
def update_figure(self):
self.fig.suptitle('测试动态图')
l = [random.randint(0, 10) for i in range(4)]
self.axes.plot([0, 1, 2, 3], l, 'r')
self.axes.set_ylabel('动态图:Y轴')
self.axes.set_xlabel('动态图:X轴')
self.axes.grid(True)
self.draw()
self.axes.clear()
def OnTimer(self):
global user, sys2, idle, bg
tmp = get_cpu_usage()
user = user[1:] + [tmp[0]]
sys2 = sys2[1:] + [tmp[1]]
idle = idle[1:] + [tmp[2]]
self.l_user.set_ydata(user)
self.l_sys.set_ydata(sys2)
self.l_idle.set_ydata(idle)
self.axes.draw_artist(self.l_user)
self.axes.draw_artist(self.l_sys)
self.axes.draw_artist(self.l_idle)
self.axes.figure.canvas.draw()
class MatplotlibWidget(QWidget):
def __init__(self, parent=None):
super(MatplotlibWidget, self).__init__(parent)
self.initUi()
def initUi(self):
self.layout = QVBoxLayout(self)
self.mpl = MyMplCanvas(self, width=10, height=8, dpi=100)
# self.mpl.start_static_plot() # 如果你想要初始化的时候就呈现静态图,请把这行注释去掉
#self.mpl.start_dynamic_plot() # 如果你想要初始化的时候就呈现动态图,请把这行注释去掉
self.mpl_ntb = NavigationToolbar(self.mpl, self) # 添加完整的 toolbar
self.layout.addWidget(self.mpl)
self.layout.addWidget(self.mpl_ntb)
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = MatplotlibWidget()
#ui.mpl.start_static_plot() # 测试静态图效果
ui.mpl.start_dynamic_plot() # 测试动态图效果
ui.show()
sys.exit(app.exec_())
matplotlib嵌入Pyqt5实现CPU信息动态曲线
最新推荐文章于 2024-05-05 18:19:47 发布