如何在0到平均值的y值之间的分布图上绘制平均值线?

时间:2020-08-07 18:32:51

标签: python matplotlib seaborn distribution

我有一个分布图,我想绘制一条从0到平均频率y值的平均线。 I want to do this,但在distplot停止时使行停止。为什么没有一个简单的参数可以做到这一点?这将非常有用。

我有一些代码可以帮助我实现目标:

plt.plot([x.mean(),x.mean()], [0, *what here?*])

除了我想要的y值外,这段代码按照我的意愿绘制一条线。要使y max停止在distplot中的均值频率处,正确的数学运算是什么?下面是我的一个散布图的示例,其中使用0.6作为y-max。如果有一些数学运算将其停在平均值的y值上,那就太了不起了。我尝试过将平均值除以计数等。

enter image description here

2 个答案:

答案 0 :(得分:7)

ax.lines[0]获取kde的曲线,您可以从中提取x和y数据。 np.interp然后可以找到给定x值的曲线高度:

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

x = np.random.normal(np.tile(np.random.uniform(10, 30, 5), 50), 3)
ax = sns.kdeplot(x, shade=True, color='crimson')
kdeline = ax.lines[0]
mean = x.mean()
height = np.interp(mean, kdeline.get_xdata(), kdeline.get_ydata())
ax.vlines(mean, 0, height, color='crimson', ls=':')
ax.set_ylim(ymin=0)
plt.show()

example plot

可以扩展相同的方法以显示均值以及标准差或中位数和四分位数:

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

x = np.random.normal(np.tile(np.random.uniform(10, 30, 5), 50), 3)
fig, axes = plt.subplots(ncols=2, figsize=(12, 4))
for ax in axes:
    sns.kdeplot(x, shade=True, color='crimson', ax=ax)
    kdeline = ax.lines[0]
    xs = kdeline.get_xdata()
    ys = kdeline.get_ydata()
    if ax == axes[0]:
        middle = x.mean()
        sdev = x.std()
        left = middle - sdev
        right = middle + sdev
        ax.set_title('Showing mean and sdev')
    else:
        left, middle, right = np.percentile(x, [25, 50, 75])
        ax.set_title('Showing median and quartiles')
    ax.vlines(middle, 0, np.interp(middle, xs, ys), color='crimson', ls=':')
    ax.fill_between(xs, 0, ys, where=(left <= xs) & (xs <= right), interpolate=True, facecolor='crimson', alpha=0.2)
    ax.set_ylim(ymin=0)
plt.show()

sdev, median, quartiles

PS:用于kde的模式:

    mode_idx = np.argmax(ys)
    ax.vlines(xs[mode_idx], 0, ys[mode_idx], color='lime', ls='--')

答案 1 :(得分:2)

使用plt.get_ylim(),您可以获取当前图的限制:[底部顶部]。
因此,根据您的情况,您可以提取实际限制并将其保存在ylim中,然后画线:

fig, ax = plt.subplots()

ylim = ax.get_ylim()
ax.plot([x.mean(),x.mean()], ax.get_ylim())
ax.set_ylim(ylim)

ax.plot之后更改ylim时,您必须如上所述使用ax.set_ylim重新设置它们。