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

如何用Seaborn FacetGrid绘制每行对应不同变量的分面直方图?

使用Seaborn FacetGrid实现多数值变量按分类分栏的直方图网格

没问题!用Seaborn的FacetGrid完全能搞定这个需求,核心是先把你的宽格式数据转成长格式(long format)——因为Seaborn的分面工具对长数据的支持更友好。下面是具体的实现步骤和示例代码:

1. 先准备示例数据

假设你的数据框是这样的,我们先模拟一个和你描述一致的数据集:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# 生成示例数据
df = pd.DataFrame({
    "C": ["A", "B", "C", "A", "B", "C"] * 50,
    "var1": np.random.normal(0, 1, 300),
    "var2": np.random.normal(5, 2, 300),
    "var3": np.random.exponential(2, 300)
})

2. 将宽格式数据转为长格式

我们需要把多个数值列(var1、var2、var3)合并成一列,同时新增一列标记当前数值属于哪个变量。用pd.melt()就能轻松实现:

# 重塑数据:id_vars保留分类列C,value_vars指定要转换的数值列
df_long = pd.melt(df, id_vars="C", value_vars=["var1", "var2", "var3"],
                  var_name="variable", value_name="value")

转换后的长数据结构大概是这样的:

Cvariablevalue
Avar10.23
Bvar1-1.12
.........

3. 用FacetGrid绘制分面直方图

现在就可以用FacetGrid来指定行(数值变量)和列(分类类别),然后映射直方图了:

# 初始化FacetGrid:行是数值变量,列是分类C
g = sns.FacetGrid(df_long, row="variable", col="C", 
                  sharex=False, sharey=False,  # 关闭共享轴,每个子图可以自适应范围
                  height=3, aspect=0.8)  # 设置子图大小和宽高比

# 映射直方图到每个子图
g.map(sns.histplot, "value", bins=15, kde=True)  # 可以添加kde曲线,或者只保留直方图

# 调整布局,添加标题
g.set_titles(row_template="{row_name}", col_template="类别 {col_name}")
plt.tight_layout()
plt.show()

关键说明

  • 为什么要转长格式?:FacetGrid的row和col参数需要对应数据中的单个列,转长格式后,我们的"variable"列正好对应每个数值变量,完美适配行分面的需求。
  • 自定义样式:你可以根据需求调整bins数量、添加kde曲线、修改颜色(比如color="steelblue"),或者设置sharex=True让同一行的子图共享x轴。
  • 对比subplot方案:如果用subplot需要手动循环每个数值变量和分类类别,代码会繁琐很多,而FacetGrid帮你自动处理了子图的布局和映射,代码更简洁易维护。

这样就能得到你想要的网格图:每行对应一个数值列的直方图,每列对应分类变量的一个类别~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:18:17