侧边栏壁纸
  • 累计撰写 54 篇文章
  • 累计创建 31 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

技术分享-Python生成cpu对比图

nankle
2024-09-21 / 0 评论 / 0 点赞 / 13 阅读 / 8062 字
温馨提示:
本文最后更新于 2024-09-21,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

最近在微信公众号做了一个自动回复的程序,主要功能是cpu性能查询与对比,数据有限,只能对比个跑分,但是对有些人来说也是有点用的,生成的对比图可以直观的看到两个cpu的大概性能差距。其中生成的cpu对比图就是本文要介绍的代码。

下面分享实现这个功能的代码,以及相关介绍,之所以想到要生成对比图,主要是考虑回复的文字太多,大家不一定愿意看,而且格式也不好调整,生成图片简单直观。希望我做的功能对大家有用。

首先展示下效果图:

1000037085.png

生成的图片由三部分组成,标题、柱状对比图、表格,数据是从数据库中查询的,也可以使用测试数据来测试学习怎么生成。

其中的水印是用另一个程序生成的,参考另一篇文章:技术分享-Python简单几行代码实现给图片增加水印-nankle个人博客

代码实现:

import os
import matplotlib.pyplot as plt
from matplotlib import font_manager as fm
from matplotlib.table import Table

# 定义全局常量
IMAGE_DIR = '/tmp'  # 将路径写死为 /tmp

def generate_cpu_comparison_chart(data):
    """
    根据提供的数据生成CPU性能对比图。
    """
    if not data:
        return None

    # 使用固定文件名
    image_filename = 'cpu_comparison.png'
    image_path = os.path.join(IMAGE_DIR, image_filename)

    # 提取标签和值
    labels = list(data.keys())
    values = [float(item['mark'].replace(',', '')) for item in data.values()]

    # 寻找最大值
    max_value = max(values)

    # 将所有的值转换为相对于最大值的百分比
    normalized_values = [v / max_value * 100 for v in values]

    # 设置颜色
    bar_color = 'green'

    # 创建一个新的figure,并设置尺寸
    fig = plt.figure(figsize=(14, 7))

    # 使用GridSpec布局 hspace 柱状图与表格间距
    gs = plt.GridSpec(2, 1, height_ratios=[1.2, 2], hspace=0.1)

    # 创建主图
    ax = fig.add_subplot(gs[0, :])

    # 绘制条形图
    ax.barh(labels, normalized_values, color=bar_color, height=0.7)

    # 移除边框
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.spines['left'].set_visible(False)

    # 检查图例是否存在并移除
    if ax.legend_ is not None:
        ax.legend_.remove()

    # 加载字体
    fontprop = fm.FontProperties(fname='/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf')

    # 设置 Matplotlib 使用的字体为 DejaVu Sans
    plt.rcParams['font.family'] = 'DejaVu Sans'
    plt.rcParams['font.sans-serif'] = ['DejaVu Sans']

    # 设置正常显示符号
    plt.rcParams['axes.unicode_minus'] = False 

    # 添加标题和轴标签
    plt.title('CPU性能对比', fontproperties=fontprop, fontsize=40, fontweight='bold')  # 设置字体大小和加粗

    # 设置x轴刻度最小值为0,最大值为100
    plt.xlim(0, 100)

    # 调整y轴的范围,使其更加扁平
    plt.ylim(-0.6, len(labels) - 0.3)

    # 去除x轴的刻度
    ax.set_xticks([])

    # 去除y轴的刻度
    ax.set_yticks([])

    # 手动设置y轴标签的位置,并向右平移一点
    ytick_positions = [i  for i in range(len(labels))]
    for i, label in enumerate(labels):
        ax.text(+1, ytick_positions[i], label, va='center', ha='left', fontsize=16, fontweight='bold')

    # 添加文本到每个条形的上方,并始终放置在x轴的最大值处
    for i, value in enumerate(normalized_values):
        ax.text(100+5, i, f'{int(value)}%', va='center', ha='right', fontsize=16, fontweight='bold')

    # 创建信息图
    info_ax = fig.add_subplot(gs[1, :])
    info_ax.axis('off')

    # 动态构建表格行数据
    num_cpus = len(labels)
    columns = ['属性'] + labels

    # 构建表格行数据
    attributes = ['名称', '分数', '功耗', '封装', '核心', '类型']
    attribute_map = {'名称': 'name2', '分数': 'mark', '功耗': 'tdp', '封装': 'socket', '核心': 'cores', '类型': 'category'}

    rows = []
    for attr in attributes:
        attr_key = attribute_map.get(attr, attr.lower())
        row_data = [attr] + [str(data[key].get(attr_key, '')) for key in labels]
        rows.append(row_data)

    # 创建表格
    info_table = Table(info_ax, bbox=[0, 0, 1, 1])

    # 设置列宽比例
    col_widths = [1] + [4] * num_cpus
    total_width = sum(col_widths)
    normalized_col_widths = [w / total_width for w in col_widths]

    # 计算单元格宽度和高度
    num_cols = len(columns)
    num_rows = len(rows)
    cell_height = 1 / num_rows

    # 添加表格内容
    for row_index, row in enumerate(rows):
        for col_index, cell in enumerate(row):
            # 计算当前列的宽度
            cell_width = normalized_col_widths[col_index]
            # 创建单元格
            cell_obj = info_table.add_cell(row_index, col_index, 
                                           width=cell_width, 
                                           height=cell_height, 
                                           text=str(cell), 
                                           loc='center', 
                                           facecolor='lightgrey' if col_index == 0 else 'white')
            
            # 设置单元格内的文本样式
            cell_obj.get_text().set_fontsize(12)
            cell_obj.get_text().set_fontweight('bold' if col_index == 0 else 'normal')
            cell_obj.get_text().set_color('black')

    # 设置表格样式
    info_table.auto_set_font_size(False)
    info_table.set_fontsize(14)
    info_table.scale(1, 1.5)

    # 将表格添加到轴
    info_ax.add_table(info_table)

    # 调整图表的边距
    plt.subplots_adjust(left=0.05, right=0.93, top=0.9, bottom=0.05)

    # 保存图像
    if not os.path.exists(IMAGE_DIR):
        os.makedirs(IMAGE_DIR)

    plt.savefig(image_path, dpi=200, bbox_inches='tight')
    plt.close(fig)

    return image_path

# 测试数据
test_data = {
    'Intel Core i7-10700K': {'name2': 'Intel Core i7-10700K', 'mark': '50000', 'tdp': '125W', 'socket': 'LGA 1200', 'cores': '8', 'category': 'Desktop'},
    'AMD Ryzen 7 5800X': {'name2': 'AMD Ryzen 7 5800X', 'mark': '35000', 'tdp': '105W', 'socket': 'AM4', 'cores': '8', 'category': 'Desktop'}
}

# 调用测试方法
generate_cpu_comparison_chart(test_data)

上面的代码可以直接运行,运行此代码后,会在 /tmp 目录下生成名为 cpu_comparison.png 的图片

需要注意的点

中文字体问题:

fontprop = fm.FontProperties(fname='/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf')

这段代码设置了字体,如果本地没有这个字体就会乱码,可以自行下载中文字体并替换该路径。

保存的路径:

上面演示的代码路径写死,需要使用时根据情况调整。

如何本地测试:

要在本地运行上述Python代码进行测试,你需要确保你的环境中已经安装了必要的库,并且环境支持Matplotlib绘图。下面是详细的步骤:

安装依赖

确保你已经安装了matplotlib库。如果没有安装,可以通过pip来安装它:

pip install matplotlib

准备环境

确保你的Python环境可以正确地创建和显示图像。如果你是在没有图形界面(如服务器环境)上运行,则可能需要安装无头后端(例如Agg后端)来生成图像文件而不是尝试显示它们:

pip install matplotlib[aagg]

并且在脚本开始的地方添加以下代码:

import matplotlib
matplotlib.use('Agg')  # 在没有GUI的环境中使用非交互式后端

运行代码

把提供的代码保存成一个.py文件,比如叫cpu_comparison.py

执行脚本

在命令行中运行这个脚本:

python cpu_comparison.py

这将会生成一张名为cpu_comparison.png的图片,并保存在/tmp目录下(如果你的操作系统允许的话)。如果你想要改变保存的路径,可以在代码中修改IMAGE_DIR变量的值。

查看结果

图片生成后,你可以手动打开/tmp目录查看图片,或者通过其他方式展示它

如果你是在一个有图形界面的环境中(如windows),那么生成的图片会直接保存在指定路径,你可以直接打开查看。如果你是在服务器或者其他没有图形界面的环境中,你需要手动检查路径来确认图片是否成功生成。

0

评论区