Seaborn 数据可视化对密度的误解?

Seaborn data visualization misunderstanding of densities?

我正在使用 seaborn 库进行数据可视化,并尝试显示标准正态分布。这种情况下的基础知识类似于:

import numpy as np
import seaborn as sns

n=1000
N= np.random.randn(n)
fig=sns.displot(N,kind="kde")

这符合预期。当我尝试同时绘制多个分布时,我的问题就开始了。我尝试了粗暴的 N2= np.random.randn(n//2)fig=sns.displot((N,N2),kind="kde"),这 returns 两个分布(根据需要),但样本量较小的那个明显不同(并且更平坦)。无论样本大小如何,适当的密度图(或直方图)应该使图形下方的面积等于一,但显然不是这样。

知道 seaborn 与 pandas 数据帧一起工作,我尝试使用下面更复杂的代码(通常不好且效率低下,但我希望清楚)再次尝试在同一个图表上进行多个分布:

import numpy as np
import seaborn as sns
import pandas as pd
n=10000

N_1= np.reshape(np.random.randn(n),(n,1))
N_2= np.reshape(np.random.randn(int(n/2)),(int(n/2),1))
N_3= np.reshape(np.random.randn(int(n/4)),(int(n/4),1))

A_1 = np.reshape(np.array(['n1' for _ in range(n)]),(n,1))
A_2 = np.reshape(np.array(['n2' for _ in range(int(n/2))]),(int(n/2),1))
A_3 = np.reshape(np.array(['n3' for _ in range(int(n/4))]),(int(n/4),1))

F_1=np.concatenate((N_1,A_1),1)
F_2=np.concatenate((N_2,A_2),1)
F_3=np.concatenate((N_3,A_3),1)

F= pd.DataFrame(data=np.concatenate((F_1,F_2,F_3),0),columns=["datar","cat"])
F["datar"]=F.datar.astype('float')
fig=sns.displot(F,x="datar",hue="cat",kind="kde")

这再次显示了非常不同(几乎按比例缩放)的分布,证实了这种情况下的结果与我的预期不一致(即,大致重叠的分布)。我不明白这张图是如何工作的吗?有一种完全不同的方法可以在我缺少的同一张图上绘制多个分布?

无论有无数据帧,Seaborn 都能愉快地工作。数据帧的列被转换为 numpy 数组以绘制图表。

sns.displot(..., kind="kde") refers to sns.kdeplot() 有一个参数 common_norm 默认为 True。将其设置为 False 独立绘制曲线。

import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt

n = 10000

N_1 = np.random.randn(n)
N_2 = np.random.randn(n // 2) + 2
N_3 = np.random.randn(n // 4) + 4

sns.displot((N_1, N_2, N_3), kind="kde", common_norm=False)
plt.show()

请注意,对于 kdeplot,选项 common_norm 默认为 True 是有意义的,与 kdeplot 一样,您还可以使用三个单独的调用创建绘图,这些调用会自动独立。还有一个有用的选项 multiple(默认为 'layer'),可以设置为 'stack''fill'.