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

如何在FacetGrid中绘制多直方图?子图列映射错误修复方案

解决DataFrame多列直方图布局映射错误问题

问题背景

现有一个包含95列的DataFrame,列名格式为{指标}_phase{时段}_{统计类型},统计类型包括Max、Min、Avg。需要绘制3列32行的子图布局:

  • 第1列(索引0):展示所有Max值的直方图
  • 第2列(索引1):展示所有Avg值的直方图
  • 第3列(索引2):展示所有Min值的直方图
  • 每行对应一个指标+时段组合(如Var1_phase2对应一行)

当前代码使用int(i/3)来确定行索引,但由于部分指标时段缺少Min列,导致列索引的分组逻辑混乱,出现直方图映射到错误行的问题。

原因分析

原代码依赖列的遍历索引i,通过int(i/3)计算行位置,但列列表并非严格按每3个(Avg/Max/Min)为一组排列(例如Var2的部分时段只有Avg和Max列),这种计算方式会将不同指标时段的列错误分配到同一行。

解决方案

通过提取列名的前缀({指标}_phase{时段})进行分组,每个唯一前缀对应一行子图,再分别匹配对应的Max、Avg、Min列绘制到对应列的子图中:

import matplotlib.pyplot as plt
import seaborn as sns

# 创建画布
fig, axes = plt.subplots(nrows=32, ncols=3, figsize=(20, 96))
columnas_numeric = df_agg_new.select_dtypes(include=['float64', 'int64']).columns
columnas_numeric = columnas_numeric.drop('season')

# 提取所有列的前缀(去掉末尾的_Avg/_Max/_Min)
prefixes = [col.rsplit('_', 1)[0] for col in columnas_numeric]
# 获取唯一前缀,每个前缀对应一行(保持原顺序)
unique_prefixes = list(dict.fromkeys(prefixes))

# 遍历每个唯一前缀(对应每一行)
for row_idx, prefix in enumerate(unique_prefixes):
    # 匹配对应统计类型的列
    max_col = f"{prefix}_Max"
    avg_col = f"{prefix}_Avg"
    min_col = f"{prefix}_Min"
    
    # 绘制Max到第1列(索引0)
    if max_col in columnas_numeric:
        sns.histplot(
            data=df_agg_new,
            x=max_col,
            stat="count",
            kde=True,
            line_kws={'linewidth': 2},
            alpha=0.3,
            ax=axes[row_idx][0]
        )
        axes[row_idx][0].set_title(max_col, fontsize=7, fontweight="bold")
        axes[row_idx][0].tick_params(labelsize=6)
        axes[row_idx][0].set_xlabel("")
    
    # 绘制Avg到第2列(索引1)
    if avg_col in columnas_numeric:
        sns.histplot(
            data=df_agg_new,
            x=avg_col,
            stat="count",
            kde=True,
            line_kws={'linewidth': 2},
            alpha=0.3,
            ax=axes[row_idx][1]
        )
        axes[row_idx][1].set_title(avg_col, fontsize=7, fontweight="bold")
        axes[row_idx][1].tick_params(labelsize=6)
        axes[row_idx][1].set_xlabel("")
    
    # 绘制Min到第3列(索引2)
    if min_col in columnas_numeric:
        sns.histplot(
            data=df_agg_new,
            x=min_col,
            stat="count",
            kde=True,
            line_kws={'linewidth': 2},
            alpha=0.3,
            ax=axes[row_idx][2]
        )
        axes[row_idx][2].set_title(min_col, fontsize=7, fontweight="bold")
        axes[row_idx][2].tick_params(labelsize=6)
        axes[row_idx][2].set_xlabel("")

# 调整布局
fig.tight_layout()
plt.subplots_adjust(top=0.97)
fig.suptitle('Distribution plots', fontsize=10, fontweight="bold");

说明

  1. 前缀分组:通过rsplit('_', 1)[0]提取列名的指标+时段前缀,确保每个唯一前缀对应一行子图,不受列数多少影响
  2. 存在性检查:通过if col in columnas_numeric判断列是否存在,避免因缺少Min列导致的报错
  3. 严格对应:每个前缀的Max/Avg/Min列会被精确绘制到对应行的指定列,完全匹配预期布局

内容的提问来源于stack exchange,提问作者Pablo Moreira Garcia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:55:02