如何在seaborn displot上绘制正态曲线
How to draw a normal curve on seaborn displot
distplot 已弃用,取而代之的是 displot。
之前的函数有绘制正态曲线的选项。
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
ax = sns.distplot(df.extracted, bins=40, kde=False, fit=stats.norm)
fit=stats.norm
不再适用于 displot。在这个 的回答中,我看到了稍后绘制法线的方法,但是它是在一些平均为 0 左右的随机数据上完成的。
如果您想复制与 distplot
相同的图,我建议使用 histplot
。将我们的数据拟合成法线是一行代码。
import numpy as np
from scipy import stats
import seaborn as sns
x = np.random.normal(10, 3.4, size=1000)
ax = sns.histplot(x, bins=40, stat='density')
mu, std = stats.norm.fit(x)
xx = np.linspace(*ax.get_xlim(),100)
ax.plot(xx, stats.norm.pdf(xx, mu, std));
输出
seaborn.displot
is a figure-level plot where the kind
parameter specifies the approach. When kind='hist'
the parameters for seaborn.histplot
可用。
- 对于 轴水平 图,请参阅
seaborn.axisgrid.FacetGrid.map
期望数据帧列名,因此,将 pdf 映射到 seaborn.displot
,数据需要在数据帧中。
- 一个问题是
x_pdf
是为每个 axes
计算的:
x0, x1 = p1.axes[0][0].get_xlim()
- 如果多个 Facet (
sharex=False
) 的 axes
不同,则无法为 .map
中的每个 axes
获取 xlim
.
- 参考资料:
- 在
python 3.8.11
、pandas 1.3.2
、matplotlib 3.4.2
、seaborn 0.11.2
中测试
单面
.map
可以用
import pandas as pd
import seaborn as sns
import numpy as np
import scipy
# data
np.random.seed(365)
x1 = np.random.normal(10, 3.4, size=1000) # mean of 10
df = pd.DataFrame({'x1': x1})
# display(df.head(3))
x1
0 10.570932
1 11.779918
2 12.779077
# function for mapping the pdf
def map_pdf(x, **kwargs):
mu, std = scipy.stats.norm.fit(x)
x0, x1 = p1.axes[0][0].get_xlim() # axes for p1 is required to determine x_pdf
x_pdf = np.linspace(x0, x1, 100)
y_pdf = scipy.stats.norm.pdf(x_pdf, mu, std)
plt.plot(x_pdf, y_pdf, c='r')
p1 = sns.displot(data=df, x='x1', kind='hist', bins=40, stat='density')
p1.map(map_pdf, 'x1')
单面或多面
- 迭代每个轴并添加 pdf 更容易
# data
np.random.seed(365)
x1 = np.random.normal(10, 3.4, size=1000) # mean of 10
x2 = np.random.standard_normal(1000) # mean of 0
df = pd.DataFrame({'x1': x1, 'x2': x2}).melt() # create long dataframe
# display(df.head(3))
variable value
0 x1 10.570932
1 x1 11.779918
2 x1 12.779077
p1 = sns.displot(data=df, x='value', col='variable', kind='hist', bins=40, stat='density', common_bins=False,
common_norm=False, facet_kws={'sharey': True, 'sharex': False})
# extract and flatten the axes from the figure
axes = p1.axes.ravel()
# iterate through each axes
for ax in axes:
# extract the variable name
var = ax.get_title().split(' = ')[1]
# select the data for the variable
data = df[df.variable.eq(var)]
mu, std = scipy.stats.norm.fit(data['value'])
x0, x1 = ax.get_xlim()
x_pdf = np.linspace(x0, x1, 100)
y_pdf = scipy.stats.norm.pdf(x_pdf, mu, std)
ax.plot(x_pdf, y_pdf, c='r')
distplot 已弃用,取而代之的是 displot。
之前的函数有绘制正态曲线的选项。
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
ax = sns.distplot(df.extracted, bins=40, kde=False, fit=stats.norm)
fit=stats.norm
不再适用于 displot。在这个
如果您想复制与 distplot
相同的图,我建议使用 histplot
。将我们的数据拟合成法线是一行代码。
import numpy as np
from scipy import stats
import seaborn as sns
x = np.random.normal(10, 3.4, size=1000)
ax = sns.histplot(x, bins=40, stat='density')
mu, std = stats.norm.fit(x)
xx = np.linspace(*ax.get_xlim(),100)
ax.plot(xx, stats.norm.pdf(xx, mu, std));
输出
seaborn.displot
is a figure-level plot where thekind
parameter specifies the approach. Whenkind='hist'
the parameters forseaborn.histplot
可用。- 对于 轴水平 图,请参阅
- 对于 轴水平 图,请参阅
seaborn.axisgrid.FacetGrid.map
期望数据帧列名,因此,将 pdf 映射到seaborn.displot
,数据需要在数据帧中。- 一个问题是
x_pdf
是为每个axes
计算的:x0, x1 = p1.axes[0][0].get_xlim()
- 如果多个 Facet (
sharex=False
) 的axes
不同,则无法为.map
中的每个axes
获取xlim
.
- 参考资料:
- 在
python 3.8.11
、pandas 1.3.2
、matplotlib 3.4.2
、seaborn 0.11.2
中测试
单面
.map
可以用
import pandas as pd
import seaborn as sns
import numpy as np
import scipy
# data
np.random.seed(365)
x1 = np.random.normal(10, 3.4, size=1000) # mean of 10
df = pd.DataFrame({'x1': x1})
# display(df.head(3))
x1
0 10.570932
1 11.779918
2 12.779077
# function for mapping the pdf
def map_pdf(x, **kwargs):
mu, std = scipy.stats.norm.fit(x)
x0, x1 = p1.axes[0][0].get_xlim() # axes for p1 is required to determine x_pdf
x_pdf = np.linspace(x0, x1, 100)
y_pdf = scipy.stats.norm.pdf(x_pdf, mu, std)
plt.plot(x_pdf, y_pdf, c='r')
p1 = sns.displot(data=df, x='x1', kind='hist', bins=40, stat='density')
p1.map(map_pdf, 'x1')
单面或多面
- 迭代每个轴并添加 pdf 更容易
# data
np.random.seed(365)
x1 = np.random.normal(10, 3.4, size=1000) # mean of 10
x2 = np.random.standard_normal(1000) # mean of 0
df = pd.DataFrame({'x1': x1, 'x2': x2}).melt() # create long dataframe
# display(df.head(3))
variable value
0 x1 10.570932
1 x1 11.779918
2 x1 12.779077
p1 = sns.displot(data=df, x='value', col='variable', kind='hist', bins=40, stat='density', common_bins=False,
common_norm=False, facet_kws={'sharey': True, 'sharex': False})
# extract and flatten the axes from the figure
axes = p1.axes.ravel()
# iterate through each axes
for ax in axes:
# extract the variable name
var = ax.get_title().split(' = ')[1]
# select the data for the variable
data = df[df.variable.eq(var)]
mu, std = scipy.stats.norm.fit(data['value'])
x0, x1 = ax.get_xlim()
x_pdf = np.linspace(x0, x1, 100)
y_pdf = scipy.stats.norm.pdf(x_pdf, mu, std)
ax.plot(x_pdf, y_pdf, c='r')