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

如何在Seaborn jointplot中绘制分组相对频率直方图?

解决jointplot小样本组边缘图无法显示的问题

因为jointplot的hue参数默认会对所有组使用全局归一化尺度,样本量小的组边缘分布会被大样本组压制,且norm_hist参数仅作用于联合图,无法影响边缘子图。可以通过JointGrid手动拆分数据绘制,让每个组的分布按自身归一化:

具体实现代码

import seaborn as sns
import matplotlib.pyplot as plt

# 初始化JointGrid,指定变量和数据集
g = sns.JointGrid(x=var_x, y=var_y, data=df)

# 绘制每个条件的联合KDE(按自身归一化)
for cond in df['condition'].unique():
    subset = df[df['condition'] == cond]
    g.plot_joint(
        sns.kdeplot,
        data=subset,
        x=var_x, y=var_y,
        fill=True, alpha=0.7, label=cond,
        common_norm=False  # 关键:每个组独立归一化,不共享全局尺度
    )

# 处理X轴边缘图:绘制归一化的直方图+KDE
ax_x = g.ax_marg_x
for cond in df['condition'].unique():
    subset = df[df['condition'] == cond]
    sns.histplot(
        data=subset, x=var_x, ax=ax_x,
        kde=True, stat='density',  # stat='density'将直方图转为密度(归一化)
        alpha=0.5, label=cond
    )
ax_x.legend(title='Condition')

# 处理Y轴边缘图:同理
ax_y = g.ax_marg_y
for cond in df['condition'].unique():
    subset = df[df['condition'] == cond]
    sns.histplot(
        data=subset, y=var_y, ax=ax_y,
        kde=True, stat='density',
        alpha=0.5, label=cond
    )
ax_y.legend(title='Condition')

# 设置轴标签和标题
g.set_axis_labels(var_x, var_y)
plt.suptitle('Normalized Joint Distribution by Condition', y=1.02)
plt.show()

关键说明

  • 用JointGrid替代jointplot,获得对联合图、边缘子图的完全控制权
  • 联合KDE的common_norm=False:让每个组的密度分布按自身样本量计算,避免大样本组主导尺度
  • 边缘图的stat='density':将直方图转换为密度分布(总面积为1),确保小样本组的分布形状能正常显示,不会被大样本组的直方图覆盖

如果只想显示边缘KDE,把histplot替换为kdeplot即可:

sns.kdeplot(data=subset, x=var_x, ax=ax_x, fill=True, alpha=0.5, label=cond)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:52:39