双层表头DataFrame/Excel子图绘制问题:所有子图仅显示最后一类数据
双层表头Excel数据绘制子图异常修复
代码可运行但存在异常:遍历类别时,4个子图仅显示最后一类(D)的数据,无法正确关联实验与类别数据并绘制到对应子图。
需求说明
- 数据源为双层表头Excel:第一层为1-28号实验,第二层为A、N、D、V四个类别
- 每个类别对应一个子图,展示该类别下所有实验的时间序列数据(共324个数据点,采样间隔30分钟)
- Y轴为Bioluminescence(生物发光值),X轴为时间(分钟)
当前代码
df = pd.read_excel("somedata.xlsx", header=[0, 1]) experiments = list(range(1, 29)) fig, axes = plt.subplots(2, 2, figsize=(12, 8)) fig.suptitle('Zeitreihenanalyse für Experimente 1-28') categories = df.columns.get_level_values(1).unique() for category in categories: row, col = divmod(categories.get_loc(category), 2) ax = axes[row, col] for experiment in experiments: data = df.iloc[1:327, experiment].values sampling_interval = 30 # Minuten time = [t * sampling_interval for t in range(len(data))] ax.plot(time, data, label=f'Experiment {experiment}') ax.set_xlabel('time (Minutes)') ax.set_ylabel('Bioluminescence') # ax.legend() plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show()
问题原因
原代码未根据当前类别筛选对应实验列,而是直接按位置取列(df.iloc[1:327, experiment]),导致所有子图重复绘制了同一组数据(最后一类D的数据)。双层表头的列是MultiIndex结构,需通过类别筛选出对应实验列才能正确关联数据。
修复后的代码
import pandas as pd import matplotlib.pyplot as plt df = pd.read_excel("somedata.xlsx", header=[0, 1]) fig, axes = plt.subplots(2, 2, figsize=(12, 8)) fig.suptitle('Zeitreihenanalyse für Experimente 1-28') categories = df.columns.get_level_values(1).unique() sampling_interval = 30 # 采样间隔(分钟) time = [t * sampling_interval for t in range(324)] # 预先生成固定时间序列 for category in categories: # 筛选当前类别对应的所有实验列 category_cols = df.columns[df.columns.get_level_values(1) == category] # 计算子图位置 row, col = divmod(categories.get_loc(category), 2) ax = axes[row, col] # 遍历当前类别下的所有实验 for col_name in category_cols: experiment_num = col_name[0] # 从MultiIndex列名提取实验编号 data = df.loc[1:324, col_name].values # 获取对应324个数据点 ax.plot(time, data, label=f'Experiment {experiment_num}') ax.set_xlabel('time (Minutes)') ax.set_ylabel('Bioluminescence') ax.set_title(f'Kategorie {category}') ax.legend(fontsize='small') # 开启图例并调整字号避免拥挤 plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show()
关键修复点
- 按类别筛选列:用
df.columns[df.columns.get_level_values(1) == category]精准获取当前类别对应的实验列,确保子图只处理对应数据 - 预生成时间序列:时间序列固定,提前计算避免重复循环生成,提升效率
- 正确提取实验编号:从
MultiIndex列名中提取实验编号,保证图例标注准确 - 明确数据范围:用
df.loc[1:324, col_name]直接获取324个数据点,避免位置索引出错
内容的提问来源于stack exchange,提问作者karlonious
相关产品推荐
相关产品推荐

