如何在 distplot 上绘制一条介于 0 和均值 y 值之间的均值线?
How to plot a mean line on a distplot between 0 and the y value of the mean?
我有一个 distplot,我想绘制一条从 0 到平均频率的 y 值的平均线。 ,但在 distplot 出现时让线条停止。为什么没有一个简单的参数可以做到这一点?这将是非常有用的。
我有一些代码可以帮助我实现目标:
plt.plot([x.mean(),x.mean()], [0, *what here?*])
除了我想要的 y 值外,这段代码绘制了一条线,就像我想要的那样。使 y max 停止在 distplot 中均值频率处的正确数学是什么?下面是我的一个 distplots 的示例,使用 0.6 作为 y-max。如果有一些数学可以让它停在均值的 y 值上,那就太棒了。我试过将平均值除以计数等
用plt.get_ylim()
可以得到当前图的极限:[bottom, top].
因此,在您的情况下,您可以提取实际限制并将它们保存在 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,因此您必须 re-set 使用 ax.set_ylim
如上所述。
Update 用于最新版本的 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-value:
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='--')
我有一个 distplot,我想绘制一条从 0 到平均频率的 y 值的平均线。
我有一些代码可以帮助我实现目标:
plt.plot([x.mean(),x.mean()], [0, *what here?*])
除了我想要的 y 值外,这段代码绘制了一条线,就像我想要的那样。使 y max 停止在 distplot 中均值频率处的正确数学是什么?下面是我的一个 distplots 的示例,使用 0.6 作为 y-max。如果有一些数学可以让它停在均值的 y 值上,那就太棒了。我试过将平均值除以计数等
用plt.get_ylim()
可以得到当前图的极限:[bottom, top].
因此,在您的情况下,您可以提取实际限制并将它们保存在 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,因此您必须 re-set 使用 ax.set_ylim
如上所述。
Update 用于最新版本的 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-value:
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='--')