Matplotlib-如何从任何条形图的顶部到y轴绘制一条线?

时间:2019-12-26 06:39:19

标签: python matplotlib statistics

我创建了一个累积直方图。现在,我想在该直方图中从任何bin的顶部到y轴画一条线,并显示它的值,如下所示:

您能告诉我该怎么做吗? 下面是我绘制该直方图的代码:

plt.rcParams['ytick.right'] = plt.rcParams['ytick.labelright'] = True
plt.rcParams['ytick.left'] = plt.rcParams['ytick.labelleft'] = False

plt.figure(figsize=[8, 6])
plt.hist(df['days'], bins=range(0, 50, 1), color="dodgerblue", edgecolor='black'
                       ,cumulative=-1, density=True
                       ,histtype='barstacked')
plt.xlabel('Number of Days')
plt.ylabel('Density')

非常感谢您!

2 个答案:

答案 0 :(得分:2)

Oneliner:

plt.axhline(y, color='k', linestyle='dashed', linewidth=1)

使用它可以在直方图中添加一条水平线。

在上述代码段中,将y的平均值或y值替换为y。

答案 1 :(得分:0)

简单地画一条水平线会引起两个问题:

  • 将在条的顶部从左到右绘制线条。要将其隐藏起来,请使用zorder=0
  • 该行仍将在最左侧可见,因为那里没有条。使用plt.autoscale(enable=True, axis='x', tight=True)将x轴更改为“紧密”布局即可解决。

要在特定的y位置添加新的价格变动,可以获取现有价格变动的列表,创建一个包含新价格变动的列表,并将其设置为新价格变动。

要更改新添加的刻度的颜色,请先在列表中找到其索引,然后使用该索引更改刻度的颜色。

此方法的一个问题是,新的价格变动可能与现有的价格变动重叠。这可以通过遍历列表来解决,如果现有刻度线比新的刻度线更接近某些epsilon,请删除现有的刻度线。在代码示例中尚未实现。

或者,刻度值可以显示在轴的左侧,水平线的顶部。当然,如果没有足够的地方放置文本,那将导致问题。

您可能希望将特殊刻度的值四舍五入到最接近的百分之一,以防止其他刻度也显示更多的数字。

我用模拟数据创建了一个示例:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame({"days": np.random.normal(25, 10, 10000)})

plt.rcParams['ytick.right'] = plt.rcParams['ytick.labelright'] = True
plt.rcParams['ytick.left'] = plt.rcParams['ytick.labelleft'] = False

plt.figure(figsize=[8, 6])
bin_heights, _, _ = plt.hist(df['days'], bins=range(0, 50, 1), color="dodgerblue", edgecolor='black',
                             cumulative=-1, density=True,
                             histtype='barstacked')
plt.autoscale(enable=True, axis='both', tight=True)  # use axis='x' to only set the x axis tight
special_y = bin_heights[15]
# draw a horizontal line, use zorder=0 so it is drawn behind the bars
plt.axhline(special_y, 0, 1, color='red', linestyle='dashed', linewidth=1, zorder=0)

plt.yticks(list(plt.yticks()[0]) + [special_y])  # add a tick in y for special_y
# find the index of special_y in the new ticks (ticks are sorted automatically)
index_special_y = list(plt.yticks()[0]).index(special_y)
plt.gca().get_yticklabels()[index_special_y].set_color('red')  # change the color of the special tick
plt.xlabel('Number of Days')
plt.ylabel('Density')
plt.show()

example plot