Use*_*rR6 5 python plot gaussian data-fitting seaborn
我决定试一试seaborn 0.11.0 版!据我所知,使用将替换 distplot 的 displot 函数。我只是想弄清楚如何将高斯拟合绘制到直方图上。这是一些示例代码。
import seaborn as sns
import numpy as np
x = np.random.normal(size=500) * 0.1
Run Code Online (Sandbox Code Playgroud)
使用 distplot 我可以做到:
sns.distplot(x, kde=False, fit=norm)
Run Code Online (Sandbox Code Playgroud)
但是如何在 displot 或 histplot 中进行呢?
小智 10
我fit也真的很怀念这个参数。当他们弃用该功能时,他们似乎并没有替换该distplot功能。在他们堵住这个漏洞之前,我创建了一个简短的函数来将正态分布覆盖添加到我的histplot. 我只需将函数与导入一起粘贴到文件顶部,然后只需添加一行即可在需要时添加覆盖。
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
def normal(mean, std, color="black"):
x = np.linspace(mean-4*std, mean+4*std, 200)
p = stats.norm.pdf(x, mean, std)
z = plt.plot(x, p, color, linewidth=2)
data = np.random.normal(size=500) * 0.1
ax = sns.histplot(x=data, stat="density")
normal(data.mean(), data.std())
Run Code Online (Sandbox Code Playgroud)
如果您更愿意使用,stat="probability"而不是stat="density",您可以使用如下方式标准化拟合曲线:
def normal(mean, std, histmax=False, color="black"):
x = np.linspace(mean-4*std, mean+4*std, 200)
p = stats.norm.pdf(x, mean, std)
if histmax:
p = p*histmax/max(p)
z = plt.plot(x, p, color, linewidth=2)
data = np.random.normal(size=500) * 0.1
ax = sns.histplot(x=data, stat="probability")
normal(data.mean(), data.std(), histmax=ax.get_ylim()[1])
Run Code Online (Sandbox Code Playgroud)
distplot关于参数的源代码fit=与此处其他答案已经建议的非常相似;初始化一些支持数组,使用给定数据的平均值/标准差计算 PDF 值,并将线图叠加在直方图的顶部。我们可以直接将代码的相关部分“转录”为自定义函数,并使用它来绘制高斯拟合(不一定是正态分布;可以是任何连续分布)。
示例实现如下。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
def add_fit_to_histplot(a, fit=stats.norm, ax=None):
if ax is None:
ax = plt.gca()
# compute bandwidth
bw = len(a)**(-1/5) * a.std(ddof=1)
# initialize PDF support
x = np.linspace(a.min()-bw*3, a.max()+bw*3, 200)
# compute PDF parameters
params = fit.fit(a)
# compute PDF values
y = fit.pdf(x, *params)
# plot the fitted continuous distribution
ax.plot(x, y, color='#282828')
return ax
# sample data
x = np.random.default_rng(0).normal(1, 4, size=500) * 0.1
# plot histogram with gaussian fit
sns.histplot(x, stat='density')
add_fit_to_histplot(x, fit=stats.norm);
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢黑色边缘颜色或一般颜色,我们可以更改条形颜色、边缘颜色和 alpha 参数,以使输出histplot()与已弃用的distplot().
import numpy as np
# sample data
x = np.random.default_rng(0).normal(1, 4, size=500) * 0.1
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,4))
# left subplot
sns.distplot(x, kde=False, fit=stats.norm, ax=ax1)
ax1.set_title('Using distplot')
# right subplot
sns.histplot(x, stat='density', color='#1f77b4', alpha=0.4, edgecolor='none', ax=ax2)
add_fit_to_histplot(x, fit=stats.norm, ax=ax2)
ax2.set_title('Using histplot+fit');
Run Code Online (Sandbox Code Playgroud)
该答案与现有答案(1 , 2)不同,因为它在有数据的直方图上拟合高斯(或任何其他连续分布,例如伽玛)(这也是在 中绘制拟合的方式distplot())。目的是distplot()尽可能地复制 的 fit 功能。
例如,假设您有遵循泊松分布的数据,绘制其直方图并绘制其高斯拟合。对于add_fit_to_histplot(),因为支持与数据端点相关(并使用斯科特的带宽规则),所以仅在直方图上有相应数据的情况下绘制生成的高斯拟合图,这也是使用(下面的distplot()左侧子图)绘制的方式。另一方面,即使没有相应的数据,ohtotasche的函数也会绘制,即正常 pdf 的左尾被完全绘制(下面的右侧子图)。normal()
data = np.random.default_rng(0).poisson(0.5, size=500)
fig, (a1, a2) = plt.subplots(1, 2, facecolor='white', figsize=(10,4))
# left subplot
sns.histplot(data, stat='density', color='#1f77b4', alpha=0.4, edgecolor='none', ax=a1)
add_fit_to_histplot(data, fit=stats.norm, ax=a1)
a1.set_title("With add_fit_to_histplot")
# right subplot
sns.histplot(x=data, stat="density", ax=a2)
normal(data.mean(), data.std())
a2.set_title("With ohtotasche's normal function")
Run Code Online (Sandbox Code Playgroud)
抱歉我参加聚会迟到了。只需检查这是否满足您的要求。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
data = np.random.normal(size=500) * 0.1
mu, std = norm.fit(data)
# Plot the histogram.
plt.hist(data, bins=25, density=True, alpha=0.6, color='g')
# Plot the PDF.
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = norm.pdf(x, mu, std)
plt.plot(x, p, 'k', linewidth=2)
plt.show()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1430 次 |
| 最近记录: |