让 axvline 以某个 y 值结束

Ver*_*ary 2 python matplotlib histogram pandas

我正在用熊猫和 pyplot 绘制直方图。有关其他信息,我在直方图分布的某些百分位处添加了线条。我已经发现您可以axvline在整个图表的某个百分比高度上显示:

cycle_df = pd.DataFrame(results)
plot = cycle_df.plot.hist(bins=30, label='Cycle time')

plot.axvline(np.percentile(cycle_df,5), label='5%', color='red', linestyle='dashed', linewidth=2, ymax=0.25)
plot.axvline(np.percentile(cycle_df,95), label='95%', color='blue', linestyle='dashed', linewidth=2, ymax=0.25)
Run Code Online (Sandbox Code Playgroud)

是否可以让红/蓝线恰好在直方图条的末端结束以看起来平滑?

在此处输入图片说明

MSe*_*ert 5

这绝对有可能,但我不确定这是否容易处理,pandas.DataFrame.hist因为这不会返回直方图数据。你将不得不做另一个matplotlib.pyplot.hist(或numpy.hist)来获得实际的垃圾箱和高度。

但是,如果您matplotlib直接使用,这将起作用:

import matplotlib.pyplot as plt

plt.style.use('ggplot')

import numpy as np

data = np.random.normal(550, 20, 100000)

fig, ax = plt.subplots(1, 1)
plot = ax.hist(data, bins=30, label='Cycle time', color='darkgrey')

ps = np.percentile(data, [5, 95])
_, ymax = ax.get_ybound()

# Search for the heights of the bins in which the percentiles are
heights = plot[0][np.searchsorted(plot[1], ps, side='left')-1]

# The height should be the bin-height divided by the y_bound (at least if y_min is zero)
ax.axvline(ps[0], label='5%', color='red', linestyle='dashed', linewidth=2, ymax=heights[0] / ymax)
ax.axvline(ps[1], label='95%', color='blue', linestyle='dashed', linewidth=2, ymax=heights[1] / ymax)
plt.legend()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如果您不想费心计算相对高度,您也可以使用Lines2Dfrommatplotlib.lines

import matplotlib.pyplot as plt
import matplotlib.lines as mlines

plt.style.use('ggplot')

import numpy as np

data = np.random.normal(550, 20, 100000)

fig, ax = plt.subplots(1, 1)
plot = ax.hist(data, bins=30, label='Cycle time', color='darkgrey')

ps = np.percentile(data, [5, 95])

# Search for the heights of the bins in which the percentiles are
heights = plot[0][np.searchsorted(plot[1], ps, side='left')-1]

# The height should be the bin-height divided by the y_bound (at least if y_min is zero)
l1 = mlines.Line2D([ps[0], ps[0]], [0, heights[0]], label='5%', color='red', linestyle='dashed', linewidth=2)
l2 = mlines.Line2D([ps[1], ps[1]], [0, heights[1]], label='95%', color='blue', linestyle='dashed', linewidth=2)
ax.add_line(l1)
ax.add_line(l2)
plt.legend()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明