我在调整 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 图会反转,我不确定为什么会发生这种情况。所以我有两个问题正在尝试解决:
首先,我尝试更改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)
,我会得到以下图:
预先感谢您的帮助。
您正在尝试绘制一个有些不寻常的组合。
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()