Matplotlib 可视化大师系列(五):plt.pie() - 展示组成部分的饼图

Matplotlib 可视化大师系列博客总览

本系列旨在提供一份系统、全面、深入的 Matplotlib 学习指南。以下是博客列表:

  1. 基础篇plt.plot() - 绘制折线图的利刃
  2. 分布篇plt.scatter() - 探索变量关系的散点图
  3. 比较篇plt.bar()plt.barh() - 清晰对比的柱状图
  4. 统计篇plt.hist()plt.boxplot() - 洞察数据分布
  5. 占比篇plt.pie() - 展示组成部分的饼图
  6. 高级篇plt.imshow() - 绘制矩阵与图像的强大工具
  7. 专属篇绘制误差线 (plt.errorbar())、等高线 (plt.contour()) 等特殊图表
  8. 综合篇在一张图中组合多种图表类型

Matplotlib 可视化大师系列(五):plt.pie() - 展示组成部分的饼图

饼图是一种经典的图表类型,用于显示一个整体中各个组成部分的比例或百分比关系。虽然近年来饼图的使用受到一些争议(尤其在数据可视化专家中),但在恰当的场景下,它仍然是一种直观有效的工具。Matplotlib 通过 plt.pie() 函数提供了创建饼图的功能。

一、 饼图是什么?何时使用(何时避免)?

饼图是一个圆形图表,被分割成多个扇形区域,每个扇形的弧长(以及面积)代表其部分占总体的比例。所有扇形的比例加起来是100%。

适用场景(谨慎使用!)

  • 显示2-5个组成部分占整体的百分比。
  • 当需要强调一个部分与整体的关系时(例如,市场份额超过50%)。
  • 组成部分的百分比差异足够大,以便在视觉上区分。

避免使用的情况

  • 太多(>6个) 类别。小的扇形难以比较和标注。
  • 当类别比例非常接近时(例如,28%, 29%, 30%),人眼很难分辨扇形大小。
  • 当需要精确比较不同部分的大小时(条形图通常更擅长比较)。
  • 当数据不构成一个完整的"整体"时。

二、 函数原型与核心参数

plt.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, **kwargs)

核心参数详解

  1. 数据与标签:
    • x: 一维数组,每个元素代表一个扇形的大小(比例会自动计算)。
    • labels: 一个字符串序列,为每个扇形指定标签。
    • colors: 一个颜色序列,用于指定每个扇形的颜色。
  2. 百分比与格式:
    • autopct: 非常有用的参数,用于在扇形内显示百分比。
      • None(默认): 不显示。
      • '%1.1f%%': 显示一位小数的百分比(如 ‘15.2%’)。
      • '%1.0f%%': 显示整数百分比。
      • 函数: 可以自定义一个函数来格式化显示内容。
    • pctdistance: 百分比文本离圆心的距离比例(默认0.6)。
    • labeldistance: 标签文本离圆心的距离比例(默认1.1)。
  3. 外观与布局:
    • explode: 一个长度与 x 相同的数组,指定每个扇形偏离圆心的距离。例如 [0, 0.1, 0, 0] 会让第二个扇形突出显示。
    • startangle: 起始绘制角度(度),从正东方向(3点钟方向) 开始逆时针旋转。默认0。
    • shadow: 如果 True,为饼图添加阴影效果(通常不推荐,显得过时)。
    • wedgeprops: 一个字典,用于设置扇形属性,如边缘颜色(edgecolor)、线宽(linewidth)等。推荐使用 wedgeprops={'edgecolor': 'black', 'linewidth': 1} 来为扇形添加黑色边框,提高可读性。
    • textprops: 一个字典,用于设置标签和百分比文本的属性,如字体大小(fontsize)、颜色(color)等。
  4. 尺寸与位置:
    • radius: 饼图的半径,用于控制大小。
    • center: 饼图的中心点坐标。
    • frame: 如果 True,在饼图周围绘制坐标轴框架(几乎从不使用)。

三、 从入门到精通:代码示例

示例 1:基础饼图

import matplotlib.pyplot as plt

# 数据
sizes = [15, 30, 25, 10, 20] # 这些值会自动计算百分比
labels = ['Python', 'JavaScript', 'Java', 'C++', 'Others']
colors = ['gold', 'yellowgreen', 'lightcoral', 'lightskyblue', 'plum']
explode = (0, 0.1, 0, 0, 0)  # 只"突出"第二部分 'JavaScript'

fig, ax = plt.subplots(figsize=(8, 8))

# 绘制饼图
wedges, texts, autotexts = ax.pie(sizes,
                                  explode=explode,
                                  labels=labels,
                                  colors=colors,
                                  autopct='%1.1f%%',
                                  shadow=False, # 避免使用阴影
                                  startangle=90, # 从90度(正北)开始
                                  wedgeprops={'edgecolor': 'black', 'linewidth': 1} # 添加边框
                                 )

# 美化百分比文本
for autotext in autotexts:
    autotext.set_color('black')
    autotext.set_fontsize(10)
    autotext.set_weight('bold')

ax.set_title('Popular Programming Languages', fontsize=14)
# 确保饼图是正圆形
ax.axis('equal')

plt.tight_layout()
plt.show()

示例 2:环形图与自定义

环形图(Donut Chart)是饼图的一种变体,中间有一个空洞,通常用于显示多个系列或使视觉效果更轻盈。

# 数据
sizes = [15, 30, 25, 10, 20]
labels = ['Python', 'JavaScript', 'Java', 'C++', 'Others']
colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99','#ff99cc']

fig, ax = plt.subplots(figsize=(8, 8))

# 先画一个普通的饼图
wedges, texts, autotexts = ax.pie(sizes,
                                  labels=labels,
                                  colors=colors,
                                  autopct='%1.1f%%',
                                  startangle=90,
                                  pctdistance=0.85, # 百分比放远一点
                                  wedgeprops=dict(width=0.4, edgecolor='w') # 关键:width设置环的宽度
                                 )

# 在中心画一个白色的圆,使其看起来像环形图
centre_circle = plt.Circle((0,0), 0.70, fc='white')
ax.add_artist(centre_circle)

# 另一种添加中心文本的方法
ax.text(0, 0, 'Languages', ha='center', va='center', fontsize=16, fontweight='bold')

ax.axis('equal')
plt.title('Donut Chart Example', fontsize=14)
plt.tight_layout()
plt.show()

示例 3:自定义格式化与高级样式

from matplotlib import cm
import numpy as np

# 数据
data = [35, 25, 20, 15, 5]
categories = ['Electronics', 'Clothing', 'Food', 'Books', 'Other']

# 创建一个颜色映射
colors = cm.Set3(np.linspace(0, 1, len(data)))

fig, ax = plt.subplots(figsize=(9, 9))

# 自定义百分比显示函数
def make_autopct(values):
    def my_autopct(pct):
        total = sum(values)
        val = int(round(pct*total/100.0))
        # 同时显示百分比和实际值
        return '{p:.1f}%\n({v:d})'.format(p=pct, v=val)
    return my_autopct

wedges, texts, autotexts = ax.pie(data,
                                  labels=categories,
                                  colors=colors,
                                  autopct=make_autopct(data), # 使用自定义函数
                                  startangle=140,
                                  shadow=False,
                                  wedgeprops={'linewidth': 2, 'edgecolor': 'white', 'alpha': 0.9}
                                 )

# 美化文本
for text in texts:
    text.set_fontsize(11)
    text.set_fontweight('bold')
for autotext in autotexts:
    autotext.set_fontsize(9)
    autotext.set_color('darkblue')

plt.title('Sales Distribution by Category', fontsize=16, fontweight='bold')
ax.axis('equal')

plt.tight_layout()
plt.show()

四、 最佳实践与常见陷阱

  1. 最佳实践:
    • 排序数据: 将数据从大到小排序,通常从12点钟方向开始,使图表更易于阅读。
    • 限制类别数量: 坚持使用2-5个主要类别。将小的、不重要的类别合并为"其他"。
    • 直接标注: 使用 autopctplt.text() 直接在扇形上标注百分比/数值,避免让读者依赖图例。
    • 使用颜色: 使用区分度高的颜色,但确保颜色不会传达错误的顺序信息(饼图各部分本质上是无序的)。
    • 考虑条形图: 在决定使用饼图之前,先问自己一个水平的条形图是否更能清晰地进行比较。
  2. 常见陷阱:
    • 3D 饼图绝对避免使用3D饼图。它严重扭曲了扇形的感知大小。
    • 过多切片: 包含太多类别是饼图最常见的问题,会导致"饼图垃圾"。
    • 缺少标注: 不提供百分比或数值,迫使读者猜测比例。
    • 误导性整体: 确保所有部分加起来代表一个有意义的整体(100%)。

五、 总结

plt.pie() 是一个专门用于创建比例图表的工具。

  • 核心功能: 用扇形角度表示部分与整体的比例关系。
  • 关键参数x(数据), labels, autopct(百分比), explode(突出), startangle, wedgeprops(样式)。
  • 高级应用: 环形图(通过 wedgeprops={'width': x})、自定义格式化函数。
  • 使用哲学谨慎使用。饼图在特定简单场景下有效,但在大多数需要精确比较的情况下,条形图是更优的选择

掌握饼图意味着你知道何时以及如何有效地使用它,更重要的是,知道何时应该避免使用它。在下一篇文章中,我们将探索一个更高级、更强大的函数 plt.imshow(),用于可视化矩阵数据和图像。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值