第9章封面

表格给人看的是数字,图给人看的是形状。第 9 章讲两件事:matplotlib 的底层心智模型(理解了它,任何绘图报错都能自救),以及 pandas/seaborn 的高层速绘(一行出图)。

🖼️ matplotlib 心智模型:画布与坐标系

一切从这两层结构开始:figure(画布) 上放若干 axes(坐标系),绘图动作都发生在某个 axes 上:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(8, 5))   # 8×5 英寸画布 + 一个坐标系
ax.plot(data["col1"], label="第一条线")   # 在 ax 上画
ax.set_title("标题"); ax.set_xlabel("x 轴")
ax.legend(loc="best")                     # 图例自动找不挡线的地方

多子图两种姿势:

fig, axes = plt.subplots(2, 2, figsize=(10, 6))   # 2×2 网格
axes[0, 0].hist(randn(100), bins=20)              # 左上角画直方图
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)  # 共享刻度
# 对齐刻度便于跨图比较——数据分析的常见需求

⚠️ Jupyter 里记得 %matplotlib inline(新版默认已开),图才内嵌显示。

🎨 颜色、标记与线型 + 刻度与注释

plot 的第三个参数是格式串:'ko--' = 黑色圆点虚线。更可读的写法:

ax.plot(x, y, linestyle="--", color="g", marker="o",
        drawstyle="steps-post")   # 阶梯图:股价/阶跃数据必备
ax.set_xticks([0, 250, 500, 750, 1000])        # 刻度位置
ax.set_xticklabels(["零", "四分之一", "半", "四分之三", "满"],
                   rotation=30, fontsize="small")  # 刻度文字
ax.annotate("重要拐点", xy=(500, 2.2),
            xytext=(600, 3), arrowprops=dict(facecolor="black"))  # 带箭头注释
fig.savefig("fig.png", dpi=400, bbox_inches="tight")   # 保存

matplotlib 默认样式已经很专业,但全局配置可以调:plt.rc("figure", figsize=(10,10))

🐼 pandas 速绘:一行出图

DataFrame 自带绘图接口,内部调 matplotlib 但自动处理索引与图例:

df.plot()                                    # 所有数值列各一条折线
df.plot.line(legend=False)                   # 折线不要图例
df["col"].plot.barh()                        # 横向条形
df.plot.bar(stacked=True)                    # 堆叠条形(占比一览)
df.plot.area(alpha=0.5)                      # 面积图
df.plot.scatter(x="a", y="b", c="c", s=50)   # c=颜色再编码一维!
df.plot.hexbin(x="a", y="b", gridsize=25)    # 大数据量散点替代品

折线图小技巧书里有个经典案例:close_price.plot()plt.axvline(竖参考线)+ ax.set_xticks(每 5 个标签取一个)——股价不均匀采样时的标准处理。

📈 分布类图表:直方图、密度、散点

看单变量分布

df["col"].plot.hist(bins=50)                    # 直方图
df["col"].plot.density()                        # 核密度估计 KDE
df["col"].plot.hist(density=True, alpha=0.3)    # 两个归一化直方图叠加比较

看两变量关系

fig, ax = plt.subplots()
ax.scatter(trans_data["m1"], trans_data["m2"], alpha=0.5)
# Seaborn 一行完成散点 + 对角线直方图
sns.pairplot(trans_data, diag_kind="kde", plot_kws={"alpha": 0.2})

看三个变量的关系用分面网格(FacetGrid)——按类别变量切开成小图阵:

sns.catplot(x="day", y="tip_pct", row="smoker",
            col="time", kind="bar", data=tips)   # 吸烟×时段的小费率
sns.catplot(x="day", y="tip_pct", kind="box", data=tips)  # 箱线图

🧭 图表选型口诀

书里没有明说但贯穿全章的规律,帮你总结成一张速查表:

你想看什么 用什么图
趋势/时间变化 折线(plot
类别间大小比较 条形(bar/barh/stacked
单变量分布 直方图 / KDE(hist/density
两变量关系 散点(scatter/hexbin
类别×数值分布 箱线图 / 小提琴(seaborn)
多变量概览 pairplot / 分面 catplot

📌 本章小结:figure 上放 axes,画图都在 axes 上subplots(2,2) 出网格、sharex 对齐比较;pandas .plot.* 一行速绘、c= 参数让颜色再编码一维;分布用 hist/density、关系用 scatter、多维度用 seaborn 分面;savefig(dpi=400, bbox_inches="tight") 存高清图。