📊 第5章 可视化数据分析图表
📄 一句话概括

饼图把整圆当 100%,扇区角度就是占比。占比和角度是同一件事的两种说法。 startangle=90 让第一块从正上方开始,符合人的阅读习惯。 环形图靠 wedgeprops 的 width 挖空中心,那块空地可以放一个总数。

📝 本章和前面几章的关系

上一篇看分布,这一篇看占比。饼图是最容易画错、也最容易被滥用的一种图。 材料是一份六项支出:房租 2500、吃饭 1800、交通 400、娱乐 600、购物 700、其他 300。

一、六项支出,合计 6300

房租 2500(39.7%,扇区 142.9 度)、吃饭 1800(28.6%,102.9 度)。

项目 金额 占比 扇区角度
房租 2500 39.7% 142.9
吃饭 1800 28.6% 102.9
购物 700 11.1% 40.0
娱乐 600 9.5% 34.3
交通 400 6.3% 22.9
其他 300 4.8% 17.1

占比和角度是同一件事的两种说法。整圆 360 度对应 100%,乘一下就对得上。 最后一项「其他」只占 4.8%、17.1 度——已经在「看不见」的边缘了。

二、饼图的两个参数

ax.pie(vals, labels=lab, autopct='%.1f%%', startangle=90)。 autopct 给百分比格式。注意里面是两个百分号,因为 % 在格式串里要转义。 startangle=90 让第一块从正上方开始,顺时针排。

不写 startangle 默认从右侧水平线起,第一块看起来像被切了一刀。

三、环形图:中间挖空

ax.pie(..., wedgeprops=dict(width=0.4)),width 是环的厚度。 0.4 就是环厚占半径的四成,剩下六成是空的。 中间那块空地可以放一个总数:六项合计 6300 元。

环形图的唯一好处就是那块空地。没有要在中间放的东西,就用普通饼图。

四、饼图的三条硬规矩

规矩 原因
块数不超过 6 再多就分不清谁大谁小
不要 3D 3D 会把前面的块拉大,视觉上骗人
必须标百分比 不标就只能靠眼睛估

还有一条没进表:各部分必须加起来 100%,有「其他」也得占一块。 柱形图能替代九成的饼图。要占比就把百分比标在柱子上,比看角度准得多。

五、动手 Demo:饼形图与环形图

先算六项支出的占比和扇区角度,再画饼图和环形图各一张。 最后对比一下有多少块落进了「30 度以下」的区域。

import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

LAB = ["房租", "吃饭", "交通", "娱乐", "购物", "其他"]
VAL = [2500, 1800, 400, 600, 700, 300]
TOT = sum(VAL)

for a, b in zip(LAB, VAL):
    print("%s %4d 元  %4.1f%%  %5.1f 度" % (a, b, b * 100.0 / TOT, b * 360.0 / TOT))

fig, ax = plt.subplots(figsize=(5, 5))
ax.pie(VAL, labels=LAB, autopct="%.1f%%", startangle=90)
ax.set_title("月度支出构成")
fig.savefig("pie.png")

fig, ax = plt.subplots(figsize=(5, 5))
ax.pie(VAL, labels=LAB, autopct="%.1f%%", startangle=90,
       wedgeprops=dict(width=0.4))
ax.set_title("月度支出构成(环形)")
fig.savefig("donut.png")
print("两张图 %d / %d 字节" % (os.path.getsize("pie.png"),
                                os.path.getsize("donut.png")))

实跑输出:

--------------------------------------------------------------------
饼形图与环形图
--------------------------------------------------------------------

  ① 一份支出构成
  --------------------------------------------------------------------
  六项合计 6300 元。占比最大的是房租 2500,39.7%。
  房租 2500 元,39.7%,扇区 142.9 度。
  吃饭 1800 元,28.6%,扇区 102.9 度。
  交通 400 元,6.3%,扇区 22.9 度。
  娱乐 600 元,9.5%,扇区 34.3 度。
  购物 700 元,11.1%,扇区 40.0 度。
  其他 300 元,4.8%,扇区 17.1 度。
  ! 占比和角度是同一件事的两种说法:整圆 360 度对应 100%。

  ② 饼图:autopct 与 startangle
  --------------------------------------------------------------------
  autopct 给百分比格式,startangle=90 让第一块从正上方开始。
  不写 startangle 默认从右侧水平线起,第一块看起来像被切了一刀。
  ! startangle=90 是饼图最好记的一条。从 12 点方向顺时针排,符合人的阅读习惯。

  ③ 环形图:中间挖空
  --------------------------------------------------------------------
  wedgeprops 里的 width 是环的宽度,0.4 就是环厚占半径的四成。
  中间空出来的地方可以放一个总数:六项合计 6300 元。
  ! 环形图的唯一好处就是中间那块空地。放个关键数字,或者干脆不用环形。

  ④ 饼图的三条硬规矩
  --------------------------------------------------------------------

| 规矩 | 原因 |
|---|---|
| 块数不超过 6 | 再多就分不清谁大谁小 |
| 不要 3D | 3D 会把前面的块拉大,视觉上骗人 |
| 必须标百分比 | 不标就只能靠眼睛估 |

  还有一条没写进表里的:饼图的各部分必须加起来是 100%,有「其他」也得占一块。
  ! 柱形图能替代九成的饼图。要占比就标百分比在柱子上,比看角度准得多。

autopct='%.1f%%' 里的两个百分号必须都写,不然会报格式化错误。 环形图比饼图多出来的只有 wedgeprops=dict(width=0.4) 这一个参数。

30 秒实验

  1. 把 startangle 去掉,对比两张图的起始位置。
  2. 把 width 改成 0.7,看环会不会细得像根线。
  3. 想一想:这六项里最小的「其他」占 4.8%,如果把六项扩到十二项会怎样?

常见误区

  1. 块数太多:扇区小于 30 度就分不清,最后只能看标签。
  2. 用 3D 饼图:前面的块被拉大,占比看起来全变了。
  3. 不标百分比:读者靠眼睛估,估出来的数没有一次是对的。
  4. 各部分加起来不等于 100%:分母错了,所有百分比都错。
自测三问(点开对答案) 1. 扇区角度和占比怎么换算? —— 占比乘 360 得角度。100% 对应整圆 360 度,所以 39.7% 就是 142.9 度。 2. 为什么饼图块数不能多? —— 块越多每块角度越小。30 度以下人眼分不清大小,图就失去意义。 3. 环形图比饼图多解决了什么? —— 中间挖出一块空地,可以放总数或关键指标,省一个标题位。

占比看完了。下一篇看关系:散点图和面积图。

相关笔记