Data Science for Beginners 第 11 课实战:用 Pandas 与 Matplotlib 以饼图、环形图、华夫图可视化蘑菇数据集的占比
本篇技术指南围绕数据科学入门课程第 11 课“Visualizing Proportions(可视化占比)”展开,基于仓库中的真实蘑菇数据集 data/mushrooms.csv,演示从全文本列的数据准备、groupby 分组统计,到用 Matplotlib 绘制饼图(Pie)、环形图(Donut)、用 PyWaffle 绘制华夫图(Waffle)的完整流程。读完后,你可以独立完成“按类别分组 → 计算占比 → 选择合适图表类型呈现比例”这一数据可视化的核心闭环。
课程目标与数据集
本课的核心是学习三种“占比类”(proportions)图表:
- 饼图(Pie chart)
- 环形图(Donut chart)
- 华夫图(Waffle chart)
配套课程说明见 课程 README,可交互练习在 课程 Notebook 中进行,参考答案在 solution/notebook.ipynb。
课程使用的数据集来自 Audubon 的蘑菇清单详情,涵盖 23 种伞菌科(Agaricus)和 Lepiota 属的蘑菇。仓库中的 data/mushrooms.csv 实际包含 8124 条记录和 23 个字段,导入方式如下:
import pandas as pd
import matplotlib.pyplot as plt
mushrooms = pd.read_csv('../../data/mushrooms.csv') # 相对于课程目录的路径
mushrooms.head()
23 个字段全部为文本型描述属性:
| 字段 | 含义示例 |
|---|---|
class |
可食用性:Edible / Poisonous |
cap-shape、cap-surface、cap-color |
菌盖形状、表面、颜色 |
bruises、odor |
是否有淤伤、气味 |
gill-attachment、gill-spacing、gill-size、gill-color |
菌褶附着方式、间距、大小、颜色 |
stalk-shape、stalk-root、stalk-surface-above/below-ring、stalk-color-above/below-ring |
菌柄形状、根部、环上下表面与颜色 |
veil-type、veil-color |
菌幕类型与颜色 |
ring-number、ring-type |
菌环数量与类型 |
spore-print-color |
孢子印颜色 |
population |
生长密度:Abundant、Several、Scattered、Numerous 等 |
habitat |
生境:Grasses、Leaves、Meadows、Paths、Urban、Waste、Wood |
数据准备:把全文本列转换为 category 类型
观察前几行数据可以立即发现:整张表的数据全是文本,在绘制图表前必须先做类型转换。课程用 select_dtypes 验证了这一点:
print(mushrooms.select_dtypes(["object"]).columns)
输出显示 23 列全部为 object 类型(class、cap-shape、cap-surface……直到 habitat)。课程的做法是把所有 object 列统一转换为 category:
cols = mushrooms.select_dtypes(["object"]).columns
mushrooms[cols] = mushrooms[cols].astype('category')
转换为 category 类型是 pandas 处理高基数/低基数文本列的标准手段:它降低内存占用,并让后续分组统计的语义更清晰。
转换后,按 class 分组计数即可得到占比分析的基础数据:
edibleclass = mushrooms.groupby(['class']).count()
edibleclass
分组结果与真实数据完全吻合:Edible 4208 条,Poisonous 3916 条(合计 8124 条),即可食用蘑菇略多于有毒蘑菇,比例约为 51.8% : 48.2%。
⚠️ 课程特别强调:后面构建图表
labels数组时,顺序必须与分组结果中类别出现的顺序一致,否则标签和数据会错位。务必核对分组表的行序再写标签。
饼图(Pie):最直观的占比展示
直接用分组结果的 population 列绘制饼图:
labels = ['Edible', 'Poisonous']
plt.pie(edibleclass['population'], labels=labels, autopct='%.1f %%')
plt.title('Edible?')
plt.show()
各参数要点:
x数据:edibleclass['population'],即按 class 分组后各列的计数(每个类别下所有非空计数相同,取哪一列都一样,取population仅为习惯);labels:两个类别名,顺序对应分组结果;autopct='%.1f %%':在每个扇区上自动标注百分比,保留 1 位小数;plt.title('Edible?'):图表标题。
这张饼图直观展示了蘑菇数据集中两类蘑菇的比例分布。
环形图(Donut):饼图的“挖孔”变体
环形图本质上是中间留了个洞的饼图,视觉上更清爽,中心区域还能放汇总信息。课程用蘑菇的**生境(habitat)**字段来演示。
先按生境分组:
habitat = mushrooms.groupby(['habitat']).count()
habitat
分组后共 7 个生境类别,作为环形图的标签:
labels = ['Grasses', 'Leaves', 'Meadows', 'Paths', 'Urban', 'Waste', 'Wood']
plt.pie(habitat['class'], labels=labels,
autopct='%1.1f%%', pctdistance=0.85)
center_circle = plt.Circle((0, 0), 0.40, fc='white')
fig = plt.gcf()
fig.gca().add_artist(center_circle)
plt.title('Mushroom Habitats')
plt.show()
关键实现细节:
plt.pie先画好完整饼图;plt.Circle((0, 0), 0.40, fc='white')创建一个以原点为圆心、半径 0.40、白色填充的圆;fig.gca().add_artist(center_circle)把这个圆叠加到当前坐标轴上,把饼图中心“盖住”,从而形成环形效果。
修改 0.40 这个半径值即可调整环的粗细——半径越大环越细,越小环越宽。pctdistance=0.85 控制百分比文字离圆心的距离(0 为中心、1 为边缘)。课程还提示可参考 Matplotlib 官方文档中关于饼图/环形图标签美化的示例来进一步提升可读性。
对照 data/mushrooms.csv 的实际分布,各生境占比为:Wood 3148(约 38.7%)、Grasses 2148(26.4%)、Paths 1144(14.1%)、Leaves 832(10.2%)、Urban 368(4.5%)、Meadows 292(3.6%)、Waste 192(2.4%)——森林是绝对优势生境。
华夫图(Waffle):用 2D 方块数组表达数量比例
华夫图把数量按比例拆成网格中的小方块,是另一种“看占比”的方式。课程用蘑菇的**菌盖颜色(cap-color)**做演示,需要先安装辅助库 PyWaffle:
pip install pywaffle
先选出要分组的数据段:
capcolor = mushrooms.groupby(['cap-color']).count()
capcolor
菌盖颜色共 9 种,实际计数为:Brown 2284、Green 1856、Red 1500、Yellow 1072、White 1040、Buff 168、Pink 144、Cinnamon 44、Purple 16。构建华夫图:
import pandas as pd
import matplotlib.pyplot as plt
from pywaffle import Waffle
data = {'color': ['brown', 'buff', 'cinnamon', 'green', 'pink', 'purple', 'red', 'white', 'yellow'],
'amount': capcolor['class']}
df = pd.DataFrame(data)
fig = plt.figure(
FigureClass=Waffle,
rows=100,
values=df.amount,
labels=list(df.color),
figsize=(30, 30),
colors=["brown", "tan", "maroon", "green", "pink", "purple", "red", "whitesmoke", "yellow"],
)
参数说明:
FigureClass=Waffle:让 Matplotlib 用 Waffle 类作为图形类渲染,而不是普通 Axes;rows=100:网格共 100 行(配合内部自动推算列数),数值按总量等比铺满;values=df.amount:各颜色类别的实际计数;labels/colors:类别标签与对应颜色,两者顺序必须一一对应(brown→brown、buff→tan、white→whitesmoke 等);figsize=(30, 30):正方形大画布,保证方块清晰。
从图上可以一眼看出棕色(Brown)与绿色(Green)菌盖占绝对多数——课程也特别点出“绿盖蘑菇非常多”这一反直觉的发现。PyWaffle 还支持用 Font Awesome 图标替代方块,可以把华夫图做得更生动,值得自行实验。
如何选择:饼图、环形图还是华夫图
课程的 Review & Self Study 部分指出,三者何时使用并非总是显而易见,并给出了多篇对比文章供延伸阅读(饼图 vs 环形图的优劣对比、Waffle 图的正确用法等)。结合本课实践,可归纳为一条简单的选择逻辑:
| 图表 | 适用场景 | 注意点 |
|---|---|---|
| 饼图 | 2~6 个大类、强调“部分占整体” | 类别太多会难以辨认;标签顺序必须与数据顺序一致 |
| 环形图 | 同饼图,但需要更现代的观感或中心放置标题/汇总 | 洞半径(如 0.40)决定环宽,pctdistance 控制百分比位置 |
| 华夫图 | 想让非专业读者用“数格子”的直觉感受数量比例 | 依赖 PyWaffle;适合总量可平铺成 100/1000 格的场景 |
三者共同的前提都是:先把数据 groupby 到目标类别上,统计出每类计数,再决定用哪种图呈现。这就是本课总结的核心工作流——“group → count → 选图 → 绘制”,读完这张图用户就能瞬间获得数据集的比例快照。
练习与延伸
- 🚀 课程挑战:用 Microsoft Research 的 Charticulator(拖拽式数据可视化工具,其教程同样使用本蘑菇数据集)重绘本课图表;
- 课后作业:assignment.md 要求在 Excel 中自选一份数据,制作饼图、环形图、华夫图三种图表,评分标准以图表数量分级(三个满分);
- 动手验证:本课全部代码均可在 课程 Notebook 中逐步运行,完成后可与 solution/notebook.ipynb 中的实现逐 cell 对照,确认饼图、环形图、华夫图三种输出。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00


