Python matplotlib绘制基础饼图代码示例

Ivy
Ivy
发布时间:2026-11-06| 9人浏览过
原创

详解使用Python matplotlib库绘制基础饼图的完整代码示例,涵盖环境准备、标准绘制步骤、百分比与扇区分离参数配置、中文显示设置、文件保存及常见问题排查。

在 Python 中使用 matplotlib 绘制基础饼图,核心是调用 matplotlib.pyplot.pie() 或面向对象接口 ax.pie(),传入一组非负数值列表与对应的类别标签,再配合 autopct 显示百分比、ax.axis('equal') 保证图形呈正圆形。本文直接给出从最小可运行示例、常用样式与中文配置,到添加图例与导出高清图片的完整代码及参数说明。

一、环境准备与饼图适用前提

运行本文代码需要已安装 Python 3.8 及以上版本与 matplotlib 库。如果本地环境中尚未安装,可在终端或命令行窗口中执行以下命令安装:

pip install matplotlib
命令执行验证方式(示例输出): Successfully installed matplotlib-...(若已安装则会提示 Requirement already satisfied)

在编写代码前,需要先确认手头的数据符合基础饼图的绘制条件。饼图用于展示“部分占整体的比例”,因此输入数据应当满足两个前提:第一,所有数值均为非负数(不能包含负数,且总和必须大于 0);第二,分类数量通常控制在 2 到 6 项之间。如果分类超过 7 项或各项比例极其接近,扇区与文字标签容易发生重叠,此时应将次要分类合并为“其他”项后再绘图。

Python matplotlib绘制基础饼图代码示例
图 1:使用 matplotlib 绘制基础饼图的五步标准流程与端口传递顺序

二、最小可运行的基础饼图代码示例

如果只需要快速生成一张带百分比和英文标签的基础饼图,可以直接将以下代码保存为 basic_pie.py 并在终端运行 python basic_pie.py,或者在 Jupyter Notebook 单元格中直接执行:

import matplotlib.pyplot as plt

# 1. 准备分类标签与对应数值(无需手动凑满100,matplotlib会自动计算占比)
labels = ['Product A', 'Product B', 'Product C', 'Product D']
sizes = [35, 30, 20, 15]

# 2. 创建画布与坐标轴对象
fig, ax = plt.subplots(figsize=(6, 6))

# 3. 绘制基础饼图
ax.pie(
    sizes,
    labels=labels,
    autopct='%1.1f%%',
    startangle=90
)

# 4. 固定坐标轴长宽比相等,确保饼图是正圆形而非椭圆
ax.axis('equal')
ax.set_title('Quarterly Sales Share by Product')

# 5. 展示图表窗口
plt.show()
运行结果说明(示例表现): 执行后会弹出一个 600×600 像素比例的图形窗口,窗口中央显示分成 4 个扇区的正圆饼图。从顶部 12 点钟方向(90°)开始逆时针依次排列 Product A(35.0%)、Product B(30.0%)、Product C(20.0%)与 Product D(15.0%)。

核心步骤与参数原理解析

  • 自动归一化机制(sizes):传入的 sizes = [35, 30, 20, 15] 可以是任意正数(如实际销量 [350, 300, 200, 150])。当 sum(sizes) > 1 时,ax.pie() 会自动按 x / sum(sizes) 计算每个扇区的弧度占比。
  • 百分比格式化(autopct='%1.1f%%'):该参数用于在每个扇区内部生成百分比文本。前一个 % 表示格式化占位符起始,1.1f 表示保留 1 位小数,末尾连续两个 %% 用于转义输出字面量百分号 %。若希望保留两位小数,可改为 '%1.2f%%'。
  • 起始角度(startangle=90):matplotlib 默认从 3 点钟方向(即 X 轴正半轴 0°)逆时针开始画第一个扇区。将 startangle 设为 90 后,第一个扇区会从正上方 12 点钟方向开始绘制,更符合日常阅读习惯。
  • 正圆锁定(ax.axis('equal')):当画布尺寸不是正方形(例如默认 figsize=(6.4, 4.8))时,坐标轴缩放会导致饼图被压扁成椭圆。调用 ax.axis('equal') 会强制 X 轴与 Y 轴刻度单位长度一致,确保饼图始终保持正圆。

三、支持中文、突出扇区与自定义配色的实用示例

在实际业务报表中使用饼图时,通常会遇到两个问题:一是默认字体不包含中文字形,导致中文标题和标签显示为空白方框(□□);二是需要突出显示某一个核心分类(例如占比最高或需要重点汇报的扇区)。下面的完整代码展示了如何同时配置跨平台中文字体、分离指定扇区(explode)、自定义配色(colors)以及设置文字距圆心的距离:

import matplotlib.pyplot as plt

# 1. 配置中文字体回退列表,兼容 Windows(SimHei/Microsoft YaHei)、macOS(PingFang SC) 与 Linux
plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Microsoft YaHei', 'SimHei', 'Noto Sans CJK SC']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示为方框的问题

# 2. 定义业务分类数据
labels = ['搜索引擎', '直接访问', '外部链接', '社交媒体']
sizes = [420, 260, 190, 130]

# 3. 设置扇区分离距离:仅将第1项“搜索引擎”向外抽出半径的 0.08 倍,其余保持为 0
explode = (0.08, 0, 0, 0)

# 4. 指定低饱和度工程配色(顺序与 labels 一一对应)
colors = ['#345E82', '#5B84A8', '#AD8060', '#8FA8BE']

fig, ax = plt.subplots(figsize=(7, 6), dpi=100)

# 5. 绘制饼图并接收返回值(wedges: 扇区对象列表, texts: 外部标签列表, autotexts: 内部百分比列表)
wedges, texts, autotexts = ax.pie(
    sizes,
    explode=explode,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
    pctdistance=0.62,      # 百分比文字距圆心的半径比例(默认 0.6)
    labeldistance=1.12,    # 分类标签距圆心的半径比例(默认 1.1)
    wedgeprops={'linewidth': 1.2, 'edgecolor': 'white'},  # 为扇区添加白色分隔边框
    textprops={'fontsize': 11, 'color': '#1E293B'}        # 统一设置文字字号与颜色
)

# 6. 单独将内部百分比文字设为白色加粗,提升深色背景扇区上的可读性
for autotext in autotexts:
    autotext.set_color('white')
    autotext.set_weight('bold')

ax.axis('equal')
ax.set_title('网站访问流量来源占比分析', fontsize=14, pad=16)

plt.tight_layout()
plt.show()
运行结果说明(示例表现): 生成的饼图正常显示中文标题“网站访问流量来源占比分析”及四个中文分类标签。左上方的“搜索引擎”扇区(占比 42.0%)沿径向往外分离突出,各扇区之间有清晰的 1.2pt 白色描边分隔,扇区内部显示加粗的白色百分比数字。
Python matplotlib绘制基础饼图代码示例
图 2:ax.pie() 核心参数端口与饼图极坐标几何元素的对应关系
容易出错的地方(explode 长度匹配):explode 元组或列表的元素个数必须与 sizes 完全一致。如果 sizes 有 4 个元素,而 explode 只写了 (0.1, 0),运行时会直接抛出 ValueError: 'explode' must be of length 'x'。不需要分离的扇区必须显式填 0。

四、添加独立图例并导出高清图片文件

当分类名称较长,或者某个扇区占比很小(如低于 5%)时,直接把标签写在扇区外侧容易导致文字重叠或超出画布边界。此时更稳妥的做法是:不在扇区外侧直接渲染长标签,而是利用 ax.legend() 在饼图右侧生成独立图例,并使用 plt.savefig() 将结果保存为本地图片文件。

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Microsoft YaHei', 'SimHei', 'Noto Sans CJK SC']
plt.rcParams['axes.unicode_minus'] = False

categories = [
    '云端服务器与计算节点',
    '对象存储与冷备归档',
    '内容分发网络 (CDN)',
    '关系型数据库实例',
    '域名与安全证书服务'
]
costs = [4800, 2100, 1650, 1100, 350]
colors = ['#23425D', '#345E82', '#5B84A8', '#AD8060', '#C8A98E']

fig, ax = plt.subplots(figsize=(8, 5), dpi=120)

# 不向 labels 传参,避免长文本在扇区周围拥挤,仅显示内部百分比
wedges, texts, autotexts = ax.pie(
    costs,
    colors=colors,
    autopct='%1.1f%%',
    startangle=140,
    pctdistance=0.72,
    wedgeprops={'linewidth': 1, 'edgecolor': 'white'},
    textprops={'fontsize': 10, 'color': 'white', 'weight': 'bold'}
)

# 使用 wedges 句柄挂载右侧独立图例,bbox_to_anchor 控制图例相对坐标轴的锚点位置
ax.legend(
    wedges,
    categories,
    title='月度成本构成项',
    loc='center left',
    bbox_to_anchor=(0.95, 0.5),
    frameon=True
)

ax.axis('equal')
ax.set_title('基础设施月度费用占比统计', fontsize=14, pad=14)

# 保存为本地高清 PNG 文件,bbox_inches='tight' 防止右侧外部图例被裁切
plt.savefig('cloud_cost_pie.png', dpi=300, bbox_inches='tight')
plt.show()
运行结果与文件验证(示例表现): 代码执行后,当前工作目录下会生成名为 cloud_cost_pie.png 的 300 DPI 高清图片文件。图像左侧为正圆饼图(仅含百分比),右侧整齐排列带颜色方块的“月度成本构成项”图例框,且图例边缘完整无裁切。
关键顺序提醒(先保存后显示):plt.savefig() 必须写在 plt.show() 之前。因为调用 plt.show() 并在图形窗口关闭后,matplotlib 会清空当前活动画布释放内存;如果在 plt.show() 之后再调用 plt.savefig(),导出的 PNG 文件将会是一张纯白空白图。
Python matplotlib绘制基础饼图代码示例
图 3:基础饼图常见的三类配置误区(椭圆变形、标签重叠、保存空白)与规范解法对比

五、核心参数速查与常见问题排查

为方便在编写代码时快速核对参数名称与数据类型,下表汇总了 ax.pie() 绘制基础饼图最常用的核心参数:

参数名 数据类型 默认值 作用与使用说明
x (首个位置参数) list / array 必填 各扇区的非负数值序列,内部自动按 x / sum(x) 计算弧度占比。
labels list[str] None 为每个扇区指定外侧文本标签,长度必须与 x 一致。
autopct str / callable None 控制扇区内部百分比显示格式,常用 '%1.1f%%' 或自定义函数。
explode tuple / list None 指定各扇区偏离圆心的半径比例,如 (0.1, 0, 0, 0) 突出第 1 项。
startangle float 0 逆时针绘制第 1 个扇区的起始角度,设为 90 即从正上方 12 点钟方向开始。
colors list[str] None 自定义各扇区颜色序列(支持十六进制如 '#345E82' 或颜色名)。
pctdistance float 0.6 autopct 百分比文本中心距圆心的半径比例(圆周半径为 1.0)。
labeldistance float 1.1 labels 分类名称文本距圆心的半径比例。
wedgeprops dict None 传递给扇区 Wedge 对象的属性字典,如 {'edgecolor': 'white', 'linewidth': 1}。

常见问题与解决方法

1. 数据中包含 0 或极小值时,为什么扇区上还会印出 0.0% 文字?
当 sizes 列表中存在 0(例如某分类当月数值为 0)时,即使扇区面积为 0,autopct='%1.1f%%' 仍会在该扇区对应的边界线上渲染出 0.0%,并与相邻标签发生重叠。解决方法是将一个函数传给 autopct,在占比小于阈值时返回空字符串:

# 仅当占比大于 2% 时才显示百分比数字,隐藏 0% 或极小占比文字
ax.pie(
    sizes,
    labels=labels,
    autopct=lambda pct: f'{pct:.1f}%' if pct > 2.0 else ''
)

2. 为什么修改了 plt.rcParams['font.sans-serif'] 之后中文依然显示为方框?
这通常是因为当前操作系统中没有安装列表里的第一个字体,或者在调用 plt.subplots() 之后才设置 rcParams。请确保将 plt.rcParams 放在绘图代码最上方;如果使用 Linux 服务器环境且没有预装中文字体,可以在终端运行以下命令查看系统已安装的中文字体名称,并将其填入列表首位:

python -c "import matplotlib.font_manager as fm; print([f.name for f in fm.fontManager.ttflist if 'CJK' in f.name or 'Hei' in f.name or 'Song' in f.name])"

3. 传入的数据总和小于 1(如 [0.3, 0.2, 0.1])时,为什么画出来的饼图缺了一块?
在 matplotlib 的 pie() 函数中,当 sum(x) <= 1 时,默认行为是直接将数值当作占比而不做归一化,因此总和 0.6 只会画出占圆周 60% 的扇形。如果传入的是小数但仍希望它们自动归一化填满整个圆,需要在调用时显式加上 normalize=True(适用于 matplotlib 3.3 及以上版本):

ax.pie([0.3, 0.2, 0.1], labels=['A', 'B', 'C'], autopct='%1.1f%%', normalize=True)
Python matplotlib绘制基础饼图代码示例
图 4:Python matplotlib 绘制基础饼图的参数配置与排错要点总结

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。