1. 空白画布:数据范围与坐标轴映射排查
先判断“空”发生在哪一层
画布全空通常不是绘图库坏了,而是数据或映射在某一环断了。排查顺序应从“数据是否真的进入绘图对象”开始,再看坐标轴范围是否把数据推到可视区之外。下面这张图把一次空白画布故障拆成三条并行检查链:数据读取链、坐标映射链、渲染输出链,并标出每层的典型症状与验证动作。
用最小可复现数据锁定断点
不要一上来就盯着完整数据集调参数。先构造一个只有 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、保存的图片中能看到三个标记点,再把真实数据替换进来。这样即使真实数据再次出现空白,也能快速判断是新数据引入了空列,还是范围设置又被覆盖。