【问题标题】:Add horizontal line in single hist plot in matplotlib在 matplotlib 的单个历史图中添加水平线
【发布时间】:2019-03-04 21:29:24
【问题描述】:

我想在一组条形图中的每个条形旁边绘制中间位置及其值。

鉴于matplotlib example

import numpy as np
import matplotlib.pyplot as plt


data = [[ 66386, 174296,  75131, 577908,  32015],
        [ 58230, 381139,  78045,  99308, 160454],
        [ 89135,  80552, 152558, 497981, 603535],
        [ 78415,  81858, 150656, 193263,  69638],
        [139361, 331509, 343164, 781380,  52269]]

columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
rows = ['%d year' % x for x in (100, 50, 20, 10, 5)]

values = np.arange(0, 2500, 500)
value_increment = 1000

# Get some pastel shades for the colors
colors = plt.cm.BuPu(np.linspace(0, 0.5, len(rows)))
n_rows = len(data)

index = np.arange(len(columns)) + 0.3
bar_width = 0.4

# Initialize the vertical-offset for the stacked bar chart.
y_offset = np.zeros(len(columns))

# Plot bars and create text labels for the table
cell_text = []
for row in range(n_rows):
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
    y_offset = y_offset + data[row]
    cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])
# Reverse colors and text labels to display the last value at the top.
colors = colors[::-1]
cell_text.reverse()

# Add a table at the bottom of the axes
the_table = plt.table(cellText=cell_text,
                      rowLabels=rows,
                      rowColours=colors,
                      colLabels=columns,
                      loc='bottom')

# Adjust layout to make room for the table:
plt.subplots_adjust(left=0.2, bottom=0.2)

plt.ylabel("Loss in ${0}'s".format(value_increment))
plt.yticks(values * value_increment, ['%d' % val for val in values])
plt.xticks([])
plt.title('Loss by Disaster')

plt.show()

我尝试将其插入到创建条形的for 循环中

for row in range(n_rows):
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
    med = np.median(data[row])
    xmin = row
    xmax= (row + 1)
    label = str(med) + "%"
    plt.hlines(med, xmin, xmax, label=label, linestyle="dashed")
    y_offset = y_offset + data[row]
    cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])

然而线条太长:如何获得条形宽度? 加号标签不显示并且条从单元格中心移开......!

【问题讨论】:

  • 需要设置xminxmax
  • 我试过了,但它只给出了一行
  • 改用hlines
  • 我已更新代码以包含 hline 和随之而来的问题
  • 有关条形的定位,请参阅我的答案。标签的要点是,当使用hlines 时,您只会得到 1 个标签。如果您将plt.legend() 添加到您的代码中,它将绘制图例,您会明白为什么这并不理想。将实际中位数作为annotation 放在每个条形旁边可能会更好...

标签: python matplotlib histogram


【解决方案1】:

对于定位:

我稍微修改了您的代码。 关键是bar 默认绘制居中的条(请参阅总是有帮助的docs),因此您需要将hlines 设置为从中心 - 0.5 条宽度到中心 + 0.5 条宽度:

# Plot bars and create text labels for the table
cell_text = []
medians = []
for row in range(n_rows):
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
    y_offset = y_offset + data[row]
    cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])
    medians.append(np.median(data[row]))
# Reverse colors and text labels to display the last value at the top.
colors = colors[::-1]
cell_text.reverse()
# Draw the medians
h_width = 0.5 * bar_width
plt.hlines(medians, xmin=index-0.5*bar_width, xmax=index+0.5*bar_width, color="k", linestyle="dashed", linewidth=1)

这就是你得到的结果:

现在是标签

如果您使用hlineslabel=label,您仍然需要使用plt.legend() 绘制图例。

然而,问题是所有值都在图例中,如果不是不可能的话,很难将每个值与相应的行关联起来,尤其是当它们都具有相同的颜色时。更好的解决方案可能是将值放在每条虚线旁边。为此,您可以使用annotations:

# add the annotations (just after the part from above)
for i, med in enumerate(medians):
    plt.annotate(str(med) + "%", xy=(index[i], med), 
                 ha='center', va='bottom'
            )

所以你最终得到:





希望对您有所帮助并祝您编码愉快!


【讨论】:

    猜你喜欢
    • 2021-01-03
    • 1970-01-01
    • 2021-03-03
    • 2016-03-25
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多