1. 空白画布:数据范围与坐标轴映射排查

先判断“空”发生在哪一层

画布全空通常不是绘图库坏了,而是数据或映射在某一环断了。排查顺序应从“数据是否真的进入绘图对象”开始,再看坐标轴范围是否把数据推到可视区之外。下面这张图把一次空白画布故障拆成三条并行检查链:数据读取链、坐标映射链、渲染输出链,并标出每层的典型症状与验证动作。

空白画布的三条排查链 先确认数据进入绘图对象,再确认坐标范围覆盖数据,最后确认渲染输出 ① 数据读取链 源文件 / 查询结果 CSV、数据库、接口返回 列名与类型解析 x 列、y 列是否被识别为数值 缺失值与空列 全 NaN 或空字符串列 症状:绘图对象为空 len(df)=0 或 x/y 全为 NaN 验证:打印 shape、dtypes、 head() 与 isnull().sum() ② 坐标映射链 数据范围 min / max x: [0, 100],y: [5, 60] 坐标轴范围设定 自动 / 手动 set_xlim、set_ylim 范围与数据是否相交 区间重叠才可见 症状:数据在可视区外 如 xlim=(0,1) 而数据在 100 附近 验证:打印 get_xlim/get_ylim, 与数据 min/max 对比 ③ 渲染输出链 绘图对象与图层 figure / axes / artist 绘制调用与参数 plot / scatter 的 x、y 实参 透明度与颜色 alpha=0 或颜色与背景相同 症状:有数据但不可见 alpha=0、zorder 被遮挡 验证:检查 artists 数量、 alpha 与 zorder 设置 定位原则:先看数据是否为空,再看范围是否覆盖数据,最后看绘制参数是否让数据不可见

用最小可复现数据锁定断点

不要一上来就盯着完整数据集调参数。先构造一个只有 3 行、数值明确的小表,让“数据范围”和“坐标轴范围”都变成可以手算的数字,再逐步替换成真实数据。下面用 Python + Matplotlib 演示一次典型的空白画布:数据本身正常,但手动设置的 y 轴范围与数据完全不相交。

import pandas as pd
import matplotlib.pyplot as plt

# 最小可复现数据:x 在 0~2,y 在 10~30
df = pd.DataFrame({
    "x": [0, 1, 2],
    "y": [10, 20, 30],
})

print("shape:", df.shape)
print("dtypes:\n", df.dtypes)
print("isnull:\n", df.isnull().sum())
print("x range:", df["x"].min(), df["x"].max())
print("y range:", df["y"].min(), df["y"].max())

fig, ax = plt.subplots(figsize=(5, 3))
ax.plot(df["x"], df["y"], marker="o", color="#2f6fb3")

# 故意把 y 轴设成与数据不相交的区间
ax.set_ylim(0, 5)

print("xlim:", ax.get_xlim())
print("ylim:", ax.get_ylim())
print("lines:", len(ax.lines))

plt.savefig("blank_canvas.png", dpi=120)

运行后 lines 为 1,说明折线对象已经创建;但 ylim 是 (0.0, 5.0),而 y 数据在 10~30,整条线被推到画布上方之外,保存出来的图就是空白。把 set_ylim(0, 5) 改为 set_ylim(0, 35) 或直接删除该行让 Matplotlib 自动缩放,折线立即出现。这一步验证了“数据读取链正常、坐标映射链断裂”。

判断顺序可以固化为三问:绘图对象的 len(ax.lines) 或 len(ax.collections) 是否为 0?坐标轴范围与数据 min/max 是否有交集?绘制参数(alpha、color、zorder)是否让数据不可见?三问中任意一问为“是”,就对应到图中的某一条链。

常见断点与对应验证

断点位置 典型表现 快速验证
列名拼写错误 绘图时抛 KeyError,或取到全 NaN 列 打印 df.columns.tolist() 与 df.dtypes
数值列被读成字符串 坐标轴出现分类刻度,数据点挤在边缘 检查 dtypes,必要时 pd.to_numeric(errors="coerce")
手动范围与数据不相交 画布空白但 lines 不为 0 对比 get_ylim() 与 df["y"].min()/max()
范围被设成无效区间 如 set_xlim(10, 0) 导致反向或空区间 确认下限小于上限,或改用自动缩放
透明度或颜色问题 有 artist 但视觉上不可见 临时设 alpha=1、color="red" 复测

完成修复后,用同一份最小数据再跑一次,确认 get_ylim() 覆盖 10~30、保存的图片中能看到三个标记点,再把真实数据替换进来。这样即使真实数据再次出现空白,也能快速判断是新数据引入了空列,还是范围设置又被覆盖。