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

如何在Seaborn kdeplot中实现单密度图的0界分色填充

实现单密度图的左右分色填充(Seaborn + Matplotlib)

问题描述

我用Polars生成了包含treat_B字段的模拟数据,想要用Seaborn的kdeplot绘制该字段的单密度图,要求将0值左侧的填充区域设为红色,右侧设为蓝色。但添加hue="direction"参数后会生成两个独立的密度曲线,尝试设置common_norm=True和multiple='stack'也没能得到理想的单图分色效果,请问如何在保持单密度图形态的前提下实现分色填充?

解决方案

Seaborn的kdeplot通过hue参数无法直接实现单密度图的左右分色,需要结合Matplotlib的fill_between函数手动填充区域。核心思路是:先绘制完整的密度曲线,提取曲线的x、y数据,再分别对0左侧和右侧的区域进行填充。

完整代码实现

import polars as pl
import numpy as np
import seaborn as sb
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

TRIALS = int(10e3)
RATE_A = 0.65
RATE_B = 0.66
SIMS = int(4e3)

np.random.seed(42)

# 生成模拟数据
df_sim = pl.DataFrame(
    {
        "A": np.random.binomial(TRIALS, RATE_A, SIMS) / TRIALS,
        "B": np.random.binomial(TRIALS, RATE_B, SIMS) / TRIALS,
    }
).with_columns((pl.col("B") - pl.col("A")).alias("treat_B"))

# 绘图风格设置
sb.set(style="whitegrid")
sb.set(font_scale=2)

# 初始化画布并绘制无填充的kde曲线
fig, ax = plt.subplots(figsize=(12, 8))
kde_line = sb.kdeplot(
    data=df_sim, 
    x="treat_B", 
    ax=ax,
    color="black"  # 曲线颜色可自定义
)

# 提取密度曲线的坐标数据
line = kde_line.get_lines()[0]
x_data = line.get_xdata()
y_data = line.get_ydata()

# 填充0左侧区域(红色)
ax.fill_between(x_data, 0, y_data, where=(x_data <= 0), color="red", alpha=0.5)
# 填充0右侧区域(蓝色)
ax.fill_between(x_data, 0, y_data, where=(x_data >= 0), color="blue", alpha=0.5)

# 图表美化
ax.set_xlabel("Simulated Sample Means for treat_B")
ax.set_title('4e3 Simulated Samples for treat_B')
ax.set_xticks(np.arange(-0.02, 0.04, 0.01))
ax.xaxis.set_major_formatter(mtick.PercentFormatter(1, 0))
ax.axvline(0, color='black', linestyle='--')  # 添加0值参考竖线

plt.show()

关键步骤说明

  1. 绘制基础曲线:先绘制不带填充的kde曲线,确保曲线形态是完整的单密度图;
  2. 提取曲线数据:通过get_lines()获取曲线的x、y坐标数组,为后续填充做准备;
  3. 分区域填充:利用fill_between的where参数指定填充范围,分别设置左右区域的颜色和透明度;
  4. 图表优化:添加坐标轴标签、标题、刻度格式化及参考线,提升图表可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:44:53