我正在使用seaborn绘制数据。一切都很好,直到我的指导者问我以下示例代码是如何绘制的。
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
x = np.random.normal(size=100)
sns.distplot(x)
plt.show()
此代码的结果是:
我的问题:
1- distplot如何管理此图?
2-为什么在-3
处开始绘图并在4
处结束绘图?
3- distplot是否使用任何参数函数或任何特定的数学函数来绘制这样的数据?
我使用distplot和kde绘制数据,但我想知道这些函数背后的数学原理。
这里有一些代码试图说明如何绘制kde曲线。
代码以100 xs的随机样本开头。
这些xs显示在histogram中。使用density=True
可以将直方图归一化,以使其整个区域为1。(标准情况下,直方图的条形随点数的增长而增长。在内部,将计算出完整的区域,每个条形的高度除以该面积。)
[绘制kde,在N个样本的每一个周围绘制gaussian“钟形”曲线。将这些曲线相加,然后除以N进行归一化。这些曲线的sigma
是自由参数。默认情况下,它是根据Scott的规则计算的(N ** (-1/5)
或0.4
为100点,示例图中的绿色曲线)。
下面的代码显示sigma
的不同选择的结果。较小的sigma
会更强地包围给定的数据,较大的sigma
会显得更平滑。 sigma
没有完美的选择,它很大程度上取决于数据以及有关基础分布的已知(或猜测)信息。
import matplotlib.pyplot as plt
import numpy as np
def gauss(x, mu, sigma):
return np.exp(-((x - mu) / sigma) ** 2 / 2) / (sigma * np.sqrt(2 * np.pi))
N = 100
xs = np.random.normal(0, 1, N)
plt.hist(xs, density=True, label='Histogram', alpha=.4, ec='w')
x = np.linspace(xs.min() - 1, xs.max() + 1, 100)
for sigma in np.arange(.2, 1.2, .2):
plt.plot(x, sum(gauss(x, xi, sigma) for xi in xs) / N, label=f'$\\sigma = {sigma:.1f}$')
plt.xlim(x[0], x[-1])
plt.legend()
plt.show()
PS:代替直方图或kde的其他方式来可视化100个随机数是一组短线:
plt.plot(np.repeat(xs, 3), np.tile((0, -0.05, np.nan), N), lw=1, c='k', alpha=0.5)
plt.ylim(ymin=-0.05)
或点(抖动,因此不会重叠):
plt.scatter(xs, -np.random.rand(N)/10, s=1, color='crimson')
plt.ylim(ymin=-0.099)