You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决3×4子图循环绘制的索引错误并移除空白子图

解决3×4面板图的索引错误与空白子图问题

问题原因

  • 你设置了3行4列共12个子图,但只有11列数据,循环执行12次时,第12次循环(m=11)会访问fname_col[11],而fname_col长度为11,索引仅到10,触发IndexError。
  • 最后一个子图因无数据可绘制,呈现空白。

修复方案

修改循环逻辑,仅对有数据的子图绘图,超出数据数量的子图直接移除:

修改后的代码

import matplotlib.pyplot as plt
import pandas as pd
from math import ceil

csv_path_cont = 'path_to_my_data/data.csv'
fname = pd.read_csv(csv_path_cont)

fname['time'] = pd.to_datetime(fname['time'])
fname['month'] = fname['time'].dt.strftime('%b')

# 修正索引设置:set_index默认返回新对象,需赋值或加inplace=True
fname = fname.set_index('time')

#=== 设置3x4面板图
fname_col = fname.columns[1:-2]
month_name = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']

cols = 4
rows = ceil(len(fname_col) / cols)

fig, ax = plt.subplots(rows, cols, figsize=(45,24))

m = 0
# 将二维子图数组展平,简化遍历
for sub_ax in ax.flat:
    if m < len(fname_col):
        # 绘制当前列的月度柱状图
        event_occurrence = fname[[fname_col[m],'month']][fname[fname_col[m]]>0]
        num_event = event_occurrence.groupby('month').count().reindex(month_name)
        num_event = num_event.fillna(0)
        sub_ax.bar(num_event.index, num_event[fname_col[m]])
        # 给子图设置对应列名的标题
        sub_ax.set_title(fname_col[m])
        m += 1
    else:
        # 移除空白子图
        sub_ax.remove()

# 调整子图间距,避免标题与图表重叠
fig.tight_layout()
fig.savefig('bar_chart', dpi=300)

关键修改点

  1. 修复索引越界:通过if m < len(fname_col)判断,仅在有数据时执行绘图逻辑,避免访问超出范围的列索引。
  2. 移除空白子图:对超出数据数量的子图调用sub_ax.remove()直接删除,也可替换为sub_ax.axis('off')隐藏(保留空白区域)。
  3. 优化遍历逻辑:用ax.flat将二维子图数组展平,无需嵌套循环,代码更简洁易维护。
  4. 修正标题设置:将全局的plt.title(m)改为子图的sub_ax.set_title(),确保每个子图标题对应列名,更清晰。
  5. 修正索引赋值:fname.set_index('time')需赋值给原变量,否则原DataFrame的索引不会被修改。

内容的提问来源于stack exchange,提问作者hilorywilsmart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:25:20