如何在 Seaborn 中将 KDE 图与条形图对齐?

问题描述 投票:0回答:1

我在调整 Seaborn KDE 图以将其与可视化中的带状图正确对齐时遇到困难。尽管尝试了各种方法,例如修改 bw_adjust 和手动缩放 KDE 图,但我仍未能达到预期的结果。

我的目标是在数据框中绘制 KDE 和条形图,以可视化数据分布以及相对于 KDE 的数据点可视化。带状图还使用色调来绘制以对数据进行分类。

首先,如果我单独绘制条形图,如下所示:

sns.stripplot(data=df, x="values", hue="category")

我得到以下情节:

并且,如果我单独绘制 KDE 图,如下所示:

sns.kdeplot(data=df, x="values", ax=ax)

我得到以下情节:

但是,如果我尝试将两者结合起来,如下所示:

fig, ax = plt.subplots(figsize=(16, 8))
sns.stripplot(data=df, x="values", hue="category")
sns.kdeplot(data=df, x="values", ax=ax)

我得到以下情节:

由于某种原因,当用带状图绘制时,KDE 图会反转,我不确定为什么会发生这种情况。所以我有两个问题正在尝试解决:

  1. 反转 KDE 图,使其可视化为单独绘制的情况。
  2. 沿 y 轴适当缩放 KDE 图(或带状图),以便数据点可以相对于 KDE 图很好地可视化。

首先,我尝试更改seaborn stripplot和kdeplot函数中的一些参数,如下所示:

sns.stripplot(data=df, x="values", hue="category", jitter=0.1, dodge=True, ax=ax)
sns.kdeplot(data=df, x="values", ax=ax, bw_adjust=-1)

并且,将 bw_adjust 设置为负数似乎解决了第一个问题,正如您在下面的结果中看到的那样(尽管我不确定为什么会这样):

但是,带状图的数据点仍然没有很好地表示,我不确定如何正确缩放 KDE 图以使其与带状图数据很好地吻合。

因此,为了尝试解决这个问题,我尝试手动绘制 KDE 图(不使用 seaborn):

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.stats import gaussian_kde


df = pd.read_csv("inputs/desired_data.csv")
fig, ax = plt.subplots(figsize=(16, 8))
# Strip plot
sns.stripplot(data=df, x="values", hue="category", jitter=0.1, dodge=True, ax=ax)

# Computing KDE manually
x = df["values"].values
kde = gaussian_kde(x, bw_method=1)
x_grid = np.linspace(x.min(), x.max(), 1000)
y = kde.evaluate(x_grid)

# Normalize and scale the KDE plot
y_scaled = y / y.max()  # Example normalization, adjust as needed

# Plot the scaled KDE
ax.plot(x_grid, y_scaled, color='blue')

通过这段代码,我得到以下图:

因此,我在使用带状图可视化数据点方面获得了更好的结果。然而,我又得到了一个倒置的 KDE 图。而且,如果我将

bw_method=1
中的
bw_method=-1
更改为
kde = gaussian_kde(x, bw_method=1)
,我会得到以下图:

所以,结果再次变得更糟。理想情况下,我想获得如下图:

预先感谢您的帮助。

python seaborn data-analysis kdeplot stripplot
1个回答
0
投票

您正在尝试绘制一个有些不寻常的组合。

stripplot
反转 y 轴,并设置
-0.5
0.5
之间的限制。
kdeplot
将 y 轴的最小值设置为 0(因此它“位于”x 轴上),并且高度使得曲线下的面积标准化为
1

最简单的方法是使用双轴。在原始轴上绘制

kdeplot
,在双轴上绘制
stripplot

import  seaborn as sns
import matplotlib.pyplot as plt
iris = sns.load_dataset('iris')
fig, ax = plt.subplots()
sns.kdeplot(iris, x='sepal_width', ax=ax)
ax2 = ax.twinx()
sns.stripplot(iris, x='sepal_width', hue='species', ax=ax2, palette='turbo', dodge=True)
plt.tight_layout()
plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.