matplotlib 如何在distplot上绘制0和y均值之间的均值线?

iaqfqrcu  于 2023-01-31  发布在  其他
关注(0)|答案(3)|浏览(167)

我有一个distplot,我想画一条从0到平均频率的y值的平均线,I want to do this,但是让线在distplot停止的时候停止,为什么没有一个简单的参数来做这个呢?
我有一些代码让我几乎做到了这一点:

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

这段代码绘制了一条线,除了我想要的y值。正确的数学是什么,以获得y最大停止在平均值的频率在分布图?我的一个分布图的例子是下面使用0.6作为y最大。这将是可怕的,如果有一些数学,使其停止在平均值的y值。我已经尝试除以平均值的计数等。

tct7dpnv

tct7dpnv1#

更新以获得matplotlib(3.3.4)和seaborn(0.11.1)的最新版本:现在,带有shade=True的kdeplot不再创建线对象。要获得与之前相同的结果,设置shade=False仍将创建线对象。然后,可以使用ax.fill_between()填充曲线。下面的代码相应地进行了更改。(使用revision history查看旧版本。)

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=False, color='crimson')
kdeline = ax.lines[0]
mean = x.mean()
xs = kdeline.get_xdata()
ys = kdeline.get_ydata()
height = np.interp(mean, xs, ys)
ax.vlines(mean, 0, height, color='crimson', ls=':')
ax.fill_between(xs, 0, ys, facecolor='crimson', alpha=0.2)
plt.show()

同样的方法可以扩展到显示平均值和标准差,或中位数和四分位数:

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=False, 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, facecolor='crimson', alpha=0.2)
    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()

PS:对于kde的模式:

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

kuarbcqp2#

使用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重新设置它们。

aurhwmvo

aurhwmvo3#

上面投票最多的答案确实是一个很好的解决方案。只是要注意,对于较新版本的seaborn(0.12.2),上面建议的代码需要稍微修改一下。

相关问题