Matplotlib绘制pandas含有效值行折线图出现空白图表问题
问题背景
- 现有pandas DataFrame共3095行、146列,结构示例如下:
index 5 45 60 85 6 133 ....... 137 141 number_points 0 0.35 0.63 NaN 0.78 0.84 0.67 0.84 NaN 10 1 NaN NaN NaN 0.11 NaN 0.21 0.09 NaN 4 2 NaN NaN NaN 0.88 NaN 0.25 NaN NaN 7 3 NaN 0.53 0.34 NaN NaN NaN NaN 0.1 5 4 NaN NaN NaN NaN NaN NaN NaN NaN 0 5 NaN NaN NaN NaN NaN NaN NaN NaN 5 3095 rows × 146 columns
- 列规则:除最后一列
number_points外,其余列名均为整数类型,代表对应天数(如列名5代表第5天),列未按天数值大小排序;number_points列用于统计每行中非空值的列总数。
绘图需求与异常现象
- 需求:绘制折线图,X轴为天数,Y轴为对应测量值。
- 部分行可正常出图,使用的示例代码如下:
# 数值来自原始数据集,与示例数据存在差异 plt.figure(figsize=(10,8)) df.iloc[1,:-1].T.plot() plt.show()
正常绘图效果:
- 异常:部分行执行相同逻辑后仅输出空白图表,无任何折线内容。
- 初步校验:执行
test.iloc[3028,:-1].unique().tolist(),确认待绘制行存在多个非空浮点值,返回结果如下:
>>> [nan, 0.611478498393178, 0.8732359604823238, 0.567957634306329, 0.5389633004976686]
执行相同绘图代码后输出空白图:
plt.figure(figsize=(10,8)) test.iloc[3028,:-1].T.plot() plt.show()
- 待解决:定位异常原因,给出排查方向与可落地方案。
排查方向与解决方案
1. 先校验待绘制序列的基础属性
出现空白图的核心原因基本都是数据类型、索引异常导致pandas无法识别绘图数据,先执行以下代码打印基础信息:
row_series = test.iloc[3028, :-1] print("序列值数据类型:", row_series.dtype) print("索引(列名)数据类型:", row_series.index.dtype) print("非空值总数:", row_series.count()) print("非空值对应天数列:", row_series.dropna().index.tolist())
- 若序列值类型为
object:说明列中混入了非浮点类型数据(比如字符串格式的数字、特殊空值标记),pandas会将其识别为分类数据而非数值,无法绘制折线。先执行强制类型转换即可:row_series = pd.to_numeric(row_series, errors='coerce') - 若索引类型不是数值/整数类型:说明列名被意外转换为字符串类文本(比如列名实际是"5"而非5),会导致X轴类型识别混乱。执行以下代码转换索引类型:
row_series.index = row_series.index.astype(int)
2. 显式清洗数据后再绘图
不要直接对切片后的原始序列绘图,一维Series调用.T没有实际转置效果,还可能因为DataFrame的视图/副本机制触发异常。先丢弃空值、按天数列排序后再绘制:
plt.figure(figsize=(10,8)) plot_series = row_series.dropna().sort_index() plot_series.plot() plt.xlabel("天数") plt.ylabel("测量值") plt.show()
3. 检查轴范围是否异常
如果上述操作后还是空白,打印自动生成的轴范围,确认是否存在范围匹配错误:
ax = plot_series.plot() print("X轴显示范围:", ax.get_xlim()) print("Y轴显示范围:", ax.get_ylim())
- 若轴范围和实际数值区间不匹配(比如Y轴范围被自动设置为远大于实际值的区间,导致折线被压缩到不可见),手动指定轴范围即可:
ax.set_ylim(plot_series.min() - 0.1, plot_series.max() + 0.1) ax.set_xlim(plot_series.index.min() - 1, plot_series.index.max() + 1)
通用稳妥绘图写法
从根源上避免切片、索引、类型问题,不要直接对行切片绘图,先将单行数据转换为「天数-测量值」的标准二维结构再绘制:
# 提取所有代表天数的列,排除number_points列 day_cols = [col for col in test.columns if col != 'number_points'] # 转换为标准两列结构 row_data = test.loc[3028, day_cols].reset_index() row_data.columns = ['day', 'value'] # 清洗数据:去空值、按天数排序 row_data = row_data.dropna().sort_values('day') # 绘图 plt.figure(figsize=(10,8)) plt.plot(row_data['day'], row_data['value']) plt.xlabel('天数') plt.ylabel('测量值') plt.show()
内容的提问来源于stack exchange,提问作者Reut
相关产品推荐
相关产品推荐

