我想绘制matplotlib中的几个“填充”内核密度估计值(KDE),如垂直violinplot
的上半部分或Joy Division未知乐趣的封面艺术的非重叠版本。如何使用matplotlib绘制多个内核密度估计值?
理想情况下,我希望matplotlib自己创建密度估计值,这样我就不必自己使用scipy's gaussian kde了。
我想绘制matplotlib中的几个“填充”内核密度估计值(KDE),如垂直violinplot
的上半部分或Joy Division未知乐趣的封面艺术的非重叠版本。如何使用matplotlib绘制多个内核密度估计值?
理想情况下,我希望matplotlib自己创建密度估计值,这样我就不必自己使用scipy's gaussian kde了。
This answer显示如何修改Matplotlib's violinplots。 这些小提琴图也可以适应只显示小提琴情节的上半部分。
pos = np.arange(1, 6)/2.0
data = [np.random.normal(0, std, size=1000) for std in pos]
violins = plt.violinplot(data, positions=pos, showextrema=False, vert=False)
for body in violins['bodies']:
paths = body.get_paths()[0]
mean = np.mean(paths.vertices[:, 1])
paths.vertices[:, 1][paths.vertices[:, 1] <= mean] = mean
一个好看的重叠变体可以通过该机构的透明度设置为0,添加edgecolor并确保绘制第一底层KDEs轻松创建:
pos = np.arange(1, 6)/2
data = [np.random.normal(0, std, size=1000) for std in pos]
violins = plt.violinplot(
data[::-1],
positions=pos[::-1]/5,
showextrema=False,
vert=False,
)
for body in violins['bodies']:
paths = body.get_paths()[0]
mean = np.mean(paths.vertices[:, 1])
paths.vertices[:, 1][paths.vertices[:, 1] <= mean] = mean
body.set_edgecolor('black')
body.set_alpha(1)
请注意,有一个名为joypy的现有程序包,建立在matplotlib之上从数据框中轻松制作出这样的“欢乐情节”。
除此之外,没有理由不使用scipy.stats.gaussian_kde
,因为它直接提供KDE。 violinplot
内部也使用它。
所以有问题的情节看起来像
from scipy.stats import gaussian_kde
import matplotlib.pyplot as plt
import numpy as np
pos = np.arange(1, 6)/2.0
data = [np.random.normal(0, std, size=1000) for std in pos]
def plot_kde(data, y0, height, ax=None, color="C0"):
if not ax: ax = plt.gca()
x = np.linspace(data.min(), data.max())
y = gaussian_kde(data)(x)
ax.plot(x,y0+y/y.max()*height, color=color)
ax.fill_between(x, y0+y/y.max()*height,y0, color=color, alpha=0.5)
for i, d in enumerate(data):
plot_kde(d, i, 0.8, ax=None)
plt.show()