scipy 使用log_scale=True时,Seaborn的histplot与Matplotlib的hist不匹配

piztneat  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(145)

我可能犯了一个愚蠢的错误,但这里是如何复制:
1.基于对数正态分布生成随机变量
1.将对数正态分布拟合到合成数据
1.使用拟合参数计算概率分布函数
1.绘制叠加在PDF上的合成变量直方图
1.它们不匹配!

import seaborn as sns
from scipy.stats import lognorm
import numpy as np

mu = 25
samples = lognorm.rvs(s=1, loc=0, scale=np.log(mu), size=10000)
shape, loc, scale = lognorm.fit(samples)
print(shape, loc, scale)

fig, ax = plt.subplots()
sns.histplot(samples, bins=50, stat="density", log_scale=True, ax=ax)
xs = np.linspace(0.1, 100, 10000)
ys = lognorm.pdf(xs, s=shape, loc=loc, scale=scale)
ax.plot(xs, ys, "r-")

字符串
x1c 0d1x的数据

o4tp2gmn

o4tp2gmn1#

我不认为scipy.stats有问题。用matplotlib绘图,我看到了很好的一致性:

from scipy.stats import lognorm
import numpy as np
import matplotlib.pyplot as plt

mu = 25
sample = lognorm.rvs(s=1, loc=0, scale=np.log(mu), size=100000)
shape, loc, scale = lognorm.fit(sample)

fig, ax = plt.subplots()
ax.set_xscale('log')
bins = np.logspace(-2, 2)
ax.hist(sample, bins=bins, density=True)
xs = np.logspace(-2, 2, 1000)
ys = lognorm.pdf(xs, s=shape, loc=loc, scale=scale)
ax.plot(xs, ys, "r-")

字符串


的数据
您还可以使用Seaborn绘制样本对数与相应正态分布的直方图。

import seaborn as sns
from scipy.stats import lognorm, norm
import numpy as np

mu = 25
sample = lognorm.rvs(s=1, loc=0, scale=np.log(mu), size=100000)
shape, loc, scale = lognorm.fit(sample)

fig, ax = plt.subplots()
sns.histplot(np.log(sample), bins=50, stat="density", ax=ax)
xs = np.linspace(-2, 5, 1000)
ys = norm.pdf(xs, loc=np.log(np.log(mu)), scale=1)
ax.plot(xs, ys, "r-")



我怀疑'density'log_scale之间的相互作用有一些不正确的地方,可能是我们对seaborn的理解。

  • 更新:参见https://github.com/mwaskom/seaborn/issues/3579了解发生了什么。显然,密度归一化是在对数转换的数据上执行的,即使数据在对数标度轴上显示为原始幅度。
  • 如果保留海运直方图的形状,但将对数标度轴替换为具有对数转换标签的线性标度轴,则曲线下面积为1.0。*
  • 换句话说,它可以被认为是对数转换数据的直方图,但在对数缩放轴上显示原始数据幅度。

这并没有解决问题,但是注意到您定义了mu=25并将scale=np.log(mu)传递给lognorm。请仔细检查这是否是您针对documentation of lognorm所要做的。
假设正态分布的随机变量X的均值为mu,标准差为sigma,则Y = exp(X)s = sigmascale = exp(mu)服从对数正态分布。

相关问题