【问题标题】:How to plot several kernel density estimates using matplotlib?如何使用 matplotlib 绘制几个内核密度估计?
【发布时间】:2017-10-09 13:03:38
【问题描述】:

我想在 matplotlib 中绘制几个“填充”内核密度估计 (KDE),例如垂直 violinplots 的上半部分或 Joy Division 的 Unknown Pleasures 封面艺术的非重叠版本。

理想情况下,我希望 matplotlib 自己创建密度估计值,这样我就不必自己使用 scipy's gaussian kde

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    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、添加边缘颜色并确保首先绘制底层 KDE,可以轻松创建漂亮的重叠变体:

    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)
    

    【讨论】:

      【解决方案2】:

      请注意,有一个名为 joypy 的现有包,它构建在 matplotlib 之上,可以轻松地从数据帧中生成此类“Joyplots”。

      除此之外,几乎没有理由不使用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()
      

      【讨论】:

        猜你喜欢
        • 2015-07-20
        • 2016-12-10
        • 2014-03-15
        • 2020-07-28
        • 1970-01-01
        • 2021-12-16
        • 2020-04-23
        • 2013-04-15
        • 1970-01-01
        相关资源
        最近更新 更多