让axvline以某个y值结束

时间:2017-08-16 23:15:33

标签: python pandas matplotlib histogram

我正在用熊猫和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)

是否可以让红色/蓝色线条直接结束直方图条的位置,以使其看起来平滑?

enter image description here

1 个答案:

答案 0 :(得分:3)

这绝对有可能,但我不确定使用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()

enter image description here

如果您不想再计算相对高度,也可以使用Lines2D中的matplotlib.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()

enter image description here