本节摘要:SOURCE 3.3–3.4 合并:静态图用 %matplotlib inline + matplotlib/seaborn;交互探索用 plotly。本节保留原文图表类型建议,并说明何时 Clear Output、如何用 Mermaid 规划报告结构而非重复画同一数据。
阅读完本节,你应当能够:
SOURCE 与第 2 章一致:经典 Notebook 常需:
%matplotlib inline import matplotlib.pyplot as plt import seaborn as sns
JupyterLab 默认内嵌;若图不显示,先查 Magic 是否执行、内核是否 Busy。
SOURCE 3.1 已用 df.plot.scatter、hist。扩展常用模式:
df["age"].hist(bins=30) plt.title("Age distribution") plt.show() sns.boxplot(data=df, x="category", y="score") plt.xticks(rotation=45) plt.show() sns.heatmap(df.corr(numeric_only=True), annot=False, cmap="coolwarm") plt.show()
| 目的 | 推荐 |
|---|---|
| 单变量分布 | hist, kdeplot |
| 类别对比 | boxplot, barplot |
| 两数值关系 | scatter, regplot |
| 相关矩阵 | heatmap |
SOURCE 3.4 强调 plotly 缩放、悬停、筛选——适合汇报演示:
import plotly.express as px fig = px.scatter(df, x="x_col", y="y_col", color="category", hover_data=["id"]) fig.show()
Notebook 体积会因 plotly HTML 膨胀——分享前 Clear Output 或导出 HTML 单文件,Git 里存无输出的 ipynb。

Markdown 格可用 Mermaid 画分析流程,与数据图互补:
同一张数据不要 mermaid 和 matplotlib 各画一遍——mermaid 表达步骤,matplotlib 表达数据。
df.sample(n=10000) 试色,再全量%timeit df.plot(...) 对比聚合后再画fig, axes = plt.subplots(2, 2) 避免开十个独立 figure⚠️ 常见坑:seaborn 新版 API 与旧版参数名不同——Shift+Tab 查当前版本签名。
💡 关键直觉:探索阶段「图比表快」——一眼看出离群比 describe 记得牢;确认后再写结论格。
第 3 章完结;第 4 章把 Notebook 纳入 Git 并导出分享。
| 你想回答的问题 | 图型 | 建议库 |
|---|---|---|
| 单一数值分布 | 直方图 / 箱线图 | matplotlib/seaborn |
| 类别间对比 | 条形图 / 箱线图 | seaborn |
| 两变量关系 | 散点图 / regplot | seaborn |
| 相关矩阵 | 热力图 | seaborn |
| 时间趋势 | 折线图 | matplotlib/plotly |
| 数据量大的交互探索 | 可缩放散点 | plotly.express |
sample = df.sample(n=10000, random_state=42) sns.scatterplot(data=sample, x="x_col", y="y_col", hue="category")
大表直接全量绘图,浏览器和 Notebook 都会卡。先用 sample 试配色、试坐标轴,确认无误再决定是否全量出图。
plt.title("7 月销售额比 6 月高 12%") 比 plt.title("sales") 对读者友好得多。plotly 交互图导出为 HTML 时会内嵌整段 JS,体积可达数百 KB。分享前判断受众:给团队审阅走 GitHub,给业务方看走 HTML 单文件,公开教程再考虑在线服务。本地 Notebook 的 Git 提交一律先 Clear Output。
一次正常 EDA,加载与清洗占六成时间,画图占四成。画图阶段不要追求一次到位:先画最小版本,看分布再决定是否需要分组、是否需要 log 变换。探索笔记里保留"失败图"和"最终图"对比,本身就是很好的分析记录。
探索出的关键图,用 plt.savefig("reports/dist_age.png", dpi=150, bbox_inches="tight") 保存,供报告引用;不要每次都重跑大表出图。保存时统一命名规则(主题_维度_日期),配合 reports/ 目录,交付时直接打包。
fig, ax = plt.subplots(figsize=(8, 4)) df["age"].hist(bins=30, ax=ax) ax.set_title("Age distribution") fig.tight_layout() fig.savefig("reports/dist_age.png", dpi=150)
比单张图更重要的是图与图之间的顺序。一份 EDA 报告建议按"数据长什么样 → 分布 → 关系 → 异常 → 结论"排图,每张图前面用一句话交代动机。读者顺着读下来,就是一次完整的推理过程,而不是图集。
在 Windows 环境画图,中文字体偶尔会显示成方框。临时解法是在绘图前指定字体:plt.rcParams["font.sans-serif"] = ["SimHei"],并加上 plt.rcParams["axes.unicode_minus"] = False 处理负号。这个问题与内核无关,属于绘图环境配置,排查时优先检查 rcParams 而不是数据。
一张图画完,立刻在下方 Markdown 格写一句结论:这张图告诉我什么,支持或推翻了哪个假设,下一步要验证什么。坚持"每图必有一句结论",你的 EDA 就从图集变成了论证链条,分享给同事时价值完全不同。
需要并排对比多个分布时,用 fig, axes = plt.subplots(1, 3, figsize=(15, 4)) 生成三格画布,分别在 axes[0]、axes[1]、axes[2] 上画图。子图共享坐标轴范围才能直观对比,记得手动设置 xlim 与 ylim 保持一致。
每张图下方标注一行图注:数据范围、筛选条件、单位。图注看似琐碎,却是防止误读的关键。同事拿到图能直接知道画的是什么、覆盖了哪些数据,不必追回代码里去猜。
一份好的 EDA 报告里,每个结论都对应至少一张图,每张图都支撑一个结论。检查时把 Markdown 格里的每句"发现"和图列表对照:找不到支撑图的结论要谨慎,画了图却没有结论的段落要么补结论要么删图。这种一一对应关系是报告可信度的基础。