前言
嗨,在之前的文章:Python神器:psutil库使用详解 中,介绍了python psutil库,获取系统运行时的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息,用于系统监控,性能分析,进程管理等场景。今天向大家介绍另一个神奇而有趣的工具——Pyecharts,配合psutil使用,它能够将监控到的数据转化为生动活泼的图表,你在数据的海洋中自如驰骋,尽情挥洒创造力。接下来就着我一起进入这个充满魔法的数据可视化世界吧!
第一章:开启魔法之门
首先,我们需要安装 Pyecharts。不用担心,它的安装过程就像是喝杯咖啡那么简单。只需要在命令行输入一行代码,Pyecharts 就会以闪电般的速度出现在你的电脑里。
pip install pyecharts
Pyecharts 是一款基于 Python 的数据可视化库,它支持多种类型的图表,包括折线图、柱状图、散点图、地理图等等,可以帮助用户快速生成高质量的图表。Pyecharts 具有以下几个特点:
- 易于上手:Pyecharts 提供了直观的 API,使得用户可以轻松地创建各种类型的图表。同时,Pyecharts
还提供了详细的文档和示例代码,方便用户参考。 - 多种类型的图表:Pyecharts 支持多种类型的图表,包括折线图、柱状图、散点图、地理图等等,用户可以根据自己的需求选择不同类型的图表。
- 丰富的交互功能:Pyecharts 提供了丰富的交互功能,包括鼠标悬停提示、数据筛选、图表联动等等,可以增强用户对数据的理解。
- 可扩展性强:Pyecharts 支持将图表嵌入到 Flask、Django 等 Web 框架中,并支持 Jupyter
Notebook、Spyder 等 Python IDE。
因此Pyecharts 是一个功能强大、易于上手的数据可视化库,能够帮助用户快速生成高质量的图表,增强对数据的理解和分析。
第二章:释放创造力
现在让我们来看看 Pyecharts 的一些常用图表示例。想象一下,你手里有一堆数据,但你不知道该如何展现它们的魅力。别担心,Pyecharts 可以帮助你释放创造力,让你的数据焕发出新的生机。
2.1 折线图:起伏的数据轨迹
根据psutil库监控内存占用并将数据保存到memory.txt中,数据格式如下图:
使用pyecharts库来自动生成内存占用折线图,并输出到memory_monitor_line.html网页上呈现,代码如下:
import os
from pyecharts import options as opts
from pyecharts.charts import Line
from pyecharts.charts import Bar
def output_memory_line_chart():
# 获取当前脚本所在的目录
cur_dir = os.path.dirname(os.path.abspath(__file__))
# 获取折线图需要绘制的数据信息
x = []
y = []
with open(cur_dir + '/memory.txt') as f:
for line in f:
space_index = line.find(' ')
if space_index != -1:
data = line[space_index + 1:] # 切片操作,保留空格之后的部分
time, per = data.strip().split()
x.append(time)
y.append(float(per)) # 将字符串转换为浮点数
line = (
Line()
.add_xaxis(x)
.add_yaxis("内存使用监控", y, label_opts=opts.LabelOpts(is_show=True))
.set_global_opts(title_opts=opts.TitleOpts(title="内存使用监控,单位:MB"))
)
line.render(path=cur_dir + '/memory_monitor_line.html')
if __name__ == '__main__':
# 调用函数生成折线图
output_memory_line_chart()
代码解释说明:
- space_index = line.find(' '):查找字符串中第一个空格的位置。
- if space_index != -1::判断是否找到了空格,避免空行导致的错误。
- data = line[space_index + 1:]:使用切片操作,获取空格之后的部分字符串。
- time, per = data.strip().split():使用strip()方法去除字符串两端的空格,并使用split()方法将字符串拆分为时间和内存占用MB两部分。
这样就可以得到每一行数据中的时间和内存占用MB,分别赋值给time和per变量。在后续的代码中,可以根据需要对这些值进行处理或者使用。
- data = line[space_index + 1:] 这行代码的作用是获取字符串 line中第一个空格后面的部分字符串,并将其赋值给变量 data。
- 这里使用了切片操作符 [start:end],其中 start表示切片的起始位置(包含),end 表示切片的结束位置(不包含),如果省略 start 或 end 则表示从字符串的开头或结尾开始切片。
- 在这里,space_index + 1 表示从第一个空格的下一个位置开始切片,即去掉了空格本身,这样就可以得到字符串中空格后面的部分。
- 例如,如果 line 的值为"2024-01-21 10:30:00 33.7",那么经过切片操作后,data 的值将为 "10:30:00 33.7"。
2.2 柱状图:高耸入云的数据墙
如果我们需要的是柱状图,代码如下:
def output_memory_bar_chart():
# 获取当前脚本所在的目录
cur_dir = os.path.dirname(os.path.abspath(__file__))
# 获取柱状图需要绘制的数据信息
x = []
y = []
with open(cur_dir + '/memory.txt') as f:
for line in f:
space_index = line.find(' ')
if space_index != -1:
data = line[space_index + 1:] # 切片操作,保留空格之后的部分
time, per = data.strip().split()
x.append(time)
y.append(float(per)) # 将字符串转换为浮点数
bar = (
Bar()
.add_xaxis(x)
.add_yaxis("内存使用监控", y, label_opts=opts.LabelOpts(is_show=True))
.set_global_opts(title_opts=opts.TitleOpts(title="内存使用监控,单位:MB"))
)
bar.render(path=cur_dir + '/memory_monitor_bar.html')
2.3 散点图:舞动的数据点
如果我们需要的是散点图,代码如下:
def output_memory_scatter_chart():
# 获取当前脚本所在的目录
cur_dir = os.path.dirname(os.path.abspath(__file__))
# 获取散点图需要绘制的数据信息
x = []
y = []
with open(cur_dir + '/memory.txt') as f:
for line in f:
space_index = line.find(' ')
if space_index != -1:
data = line[space_index + 1:] # 切片操作,保留空格之后的部分
time, per = data.strip().split()
x.append(time)
y.append(float(per)) # 将字符串转换为浮点数
scatter = (
Scatter()
.add_xaxis(x)
.add_yaxis("散点图", y, label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(title_opts=opts.TitleOpts(title="内存使用监控,单位:MB"))
)
scatter.render(path=cur_dir + '/memory_monitor_scatter.html')
第三章:解决魔法难题
细心的同学可能已经发现,上面图中x轴上的点,并没有显示我们memory.txt中数据的每一个点。原因是默认情况下,是程序根据数据间的间隔自动确定 x 轴刻度的。如果想要x轴的每一个刻度标签都显示出来,怎么办?
很简单,我们使用 xaxis_opts 中的 axislabel_opts 设置 interval=0,代码如下:
scatter = (
Scatter()
.add_xaxis(x)
.add_yaxis("散点图", y, label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="内存使用监控,单位:MB"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(interval=0)),
)
)
这样x轴上的点都显示出来了,但是细心的你会发现又出现了另一个问题:
由于点太多了,导致两个点的标签有一部分重叠显示了,看起来很不好看。怎么办呢?
方法1:调整X轴的显示方式
可以通过设置X轴的显示角度或者间隔来减少标签的重叠。例如,可以使用axislabel_opts中的rotate参数设置标签的旋转角度,或者使用interval参数设置标签的显示间隔。
scatter = (
Scatter()
.add_xaxis(x)
.add_yaxis("散点图", y, label_opts=opts.LabelOpts(is_show=True))
.set_global_opts(
title_opts=opts.TitleOpts(title="散点图"),
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(interval=0, rotate=45) # 设置标签间隔和旋转角度
),
)
)
调整后,显示效果如下:
方案2:加长x轴的显示长度
可以通过使用了 opts.InitOpts() 方法来手动设置图表的宽度和高度,比如像下面这样设置X轴比较长,也能避免重叠显示。
scatter = (
Scatter(init_opts=opts.InitOpts(width="2000px", height="600px"))
.add_xaxis(x)
.add_yaxis("散点图", y, label_opts=opts.LabelOpts(is_show=True))
.set_global_opts(
title_opts=opts.TitleOpts(title="散点图"),
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(interval=0, rotate=45) # 设置标签间隔和旋转角度
),
)
)
调整后,显示效果如下:
如果觉得柱状图、折线图中使用单一的颜色太单调,还可以通过参数visualmap_opts,设置图表是否渐变色显示:
bar = (
Bar()
.add_xaxis(x)
.add_yaxis("柱状图", y, label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="内存使用监控,单位:MB"),
visualmap_opts={"is_show": True} # 显示颜色渐变的图例
)
)
修改后的效果图如下:
第四章:魔法升级之路
感谢坚持看到这里的同学,之前的文章Python神器:psutil库使用详解 中,有一个缺陷:如果我们统计某一个程序进程占用的内存,会发现统计出来的内存占用,和window任务管理器显示的内存占用结果,存在一定的差异。之前的代码是:
def getMemSize(pid):
# 根据进程号来获取进程的内存大小
process = psutil.Process(pid)
memInfo = process.memory_info()
# rss: 该进程实际使用物理内存(包含共享库占用的全部内存)。
# vms:该进程使用的虚拟内存总量。
return memInfo.rss / 1024 / 1024
那今天我们就来解决掉这个问题,方法是:使用新的Process.memory_full_info().uss,比以前用的Process.memory_info().rss要更加的准确,这个属性只在 psutil 5.6.2 及以上版本中可用,区别在于:
- memory_info.rss 和 memory_full_info.uss 都表示进程占用的物理内存大小,但它们计算所依据的范围不同。
- memory_info.rss 只统计进程的私有物理内存大小,不包括共享内存和映射文件等。
- memory_full_info.uss统计的是进程的所有占用的私有物理内存大小,包括私有物理内存、共享内存和映射文件等。
- 因此,在新版本的 psutil 中,使用memory_full_info.uss 可以更全面地了解进程占用的物理内存大小
- 而在旧版本的 psutil 中只能使用memory_info.rss 来获取进程的物理内存占用情况
- 但这可能会导致与任务管理器上显示的值有一些差异。
比如window任务管理器统计出来飞书、网易云音乐、QQ音乐内存占用的结果如下:
我们使用新版本的memory_full_info().uss统计出来的结果如下:
而使用老版本的memory_info().rss统计出来的数据如下:
对比数据可以发现,很明显,新版的memory_full_info().uss统计出来的结果,比老方法memory_info().rss统计出来的结果,要准确很多。
第五章:完整魔法攻略
现在,如果有一个任务让你测试监控某个软件的稳定性,我们就可以通过psutil库去采集cpu/内存的监控数据,然后再使用pyecharts库根据监控存下来的数据,自动生成炫酷的图表并在HTML网页上呈现。
为方便大家使用,更新优化后的完整代码我放在了我的微信公众号:程序员杨叔 同篇文章中,需要的宝子们可以搜索并关注后,找到同篇文章查看,或者聊天窗口输入关键词:python监控,即可获取。
=================================================================================================
以上就是本次的全部内容,如果对你有帮助,麻烦点个赞+收藏+关注,一键三连啦~ 欢迎关注下方我的公众号:程序员杨叔,各类文章都会第一时间在上面发布,持续分享各类测试开发知识干货,你的支持就是作者更新最大的动力。