【问题标题】:Clipping / cropping lines and fills in matplotlib on seaborn distplot kde-function在 seaborn distplot kde-function 上剪切/裁剪线并填充 matplotlib
【发布时间】:2019-05-28 09:57:40
【问题描述】:

假设我使用 seaborn 来绘制一个分布,它的中位数和标准差是这样的:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Get data
data = np.random.randn(6000)

# Compute statistics
median = np.median(data)
sigma = np.std(data)

low = median - sigma
hi = median + sigma

# Plot
sns.distplot(data)
plt.axvline(median, c='r')
plt.axvline(low, c='k')
plt.axvline(hi, c='k')

我将如何“裁剪”或“剪裁”线条,使它们只出现在 distplot 的 kde 函数下方?结果应该是这样的(用 gimp 快速完成):

额外问题:我将如何对 plt.fill_between() 执行相同操作,以便仅填充曲线下方的区域?我想我在这里遗漏了一些简单的东西。我之前已经剪辑了对其他元素的 fill_between 调用,但我不知道如何获取函数的坐标以及如何使用线条来完成。

有没有一种简单而简洁的方法来做我想做的事?

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    一种方法是找到与kdeplot 添加到图表中的平滑线相对应的数据,并使用它的 x 和 y 坐标。

    以下代码假设图中只有一条线 --- 多条线我们必须找出哪条线对应于kdeplot 线。

    import numpy as np
    import matplotlib.pyplot as plt
    import seaborn as sns
    from scipy.interpolate import interp1d
    
    # Get data
    data = np.random.randn(6000)
    
    # Compute statistics
    median = np.median(data)
    sigma = np.std(data)
    
    low = median - sigma
    hi = median + sigma
    
    ax = sns.distplot(data)
    # get the line that sns uses for kdeplot; at this point in the code 
    # there is only one line; if there are more we need to exract the correct
    # one.
    line = ax.lines[0].get_data()
    # To get y for x=low, x=high and x=median we can interpolate the line data
    ipf = interp1d(x=line[0], y=line[1])
    
    ax.plot([low, low], [0, ipf(low)])
    ax.plot([hi, hi], [0, ipf(hi)])
    ax.plot([median, median], [0, ipf(median)]);
    

    我们可以使用线数据作为fill_between的输入。

    plt.fill_between(line[0], np.zeros(len(line[0])), line[1]);
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      您可以通过访问distplot 绘制的平滑分布线来做到这一点。至于奖励部分,我建议您提出一个新问题,不要在同一个问题中混合两个问题。

      这里的技巧是获取最接近lowmedianhigh 的x 值,然后使用plt.ylines 而不是plt.axvline 绘制一条从y=0 到所需y 的垂直线-值。

      # Plot
      ax = sns.distplot(data)
      x, y = ax.get_lines()[0].get_data()
      plt.vlines(median, 0, y[np.argmin(abs(x-median))], color='r')
      plt.vlines(low, 0, y[np.argmin(abs(x-low))], color='k')
      plt.vlines(hi, 0, y[np.argmin(abs(x-hi))], color='k')
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-18
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 1970-01-01
        • 2015-08-10
        • 2013-10-20
        • 1970-01-01
        相关资源
        最近更新 更多