gpt4 book ai didi

python - 水平堆积条形图并为每个部分添加标签

转载 作者:太空狗 更新时间:2023-10-29 17:41:29 26 4
gpt4 key购买 nike

我正在尝试在 matplotlib 中复制以下图像,看来 barh 是我唯一的选择。虽然看起来你不能堆叠 barh 图表所以我不知道该怎么做

enter image description here

如果您知道更好的 python 库来绘制这种东西,请告诉我。

这就是我能想到的所有开始:

import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt

people = ('A','B','C','D','E','F','G','H')
y_pos = np.arange(len(people))
bottomdata = 3 + 10 * np.random.rand(len(people))
topdata = 3 + 10 * np.random.rand(len(people))
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.barh(y_pos, bottomdata,color='r',align='center')
ax.barh(y_pos, topdata,color='g',align='center')
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.set_xlabel('Distance')

plt.show()

然后我将不得不使用 ax.text 单独添加标签,这会很乏味。理想情况下,我只想指定要插入的部分的宽度,然后它会用我选择的字符串更新该部分的中心。外面的标签(例如 3800)我可以稍后添加自己,它主要是在条形部分本身上的标签,并以一种我遇到问题的很好的方式创建这个堆叠方法。你甚至可以指定一个“距离”,即以任何方式的颜色跨度吗?

enter image description here

最佳答案

编辑 2:用于更多异构数据。 (我已经离开了上述方法,因为我发现每个系列使用相同数量的记录更常见)

回答问题的两个部分:

a) barh 返回它绘制的所有补丁的句柄容器。您可以使用补丁的坐标来辅助文本位置。

b) 按照 these two 对我之前提到的问题的回答(参见 Horizontal stacked bar chart in Matplotlib ),您可以通过设置“左”输入来水平堆叠条形图。

另外 c) 处理形状不太均匀的数据。

下面是处理形状不太统一的数据的一种方法,即独立处理每个段。

import numpy as np
import matplotlib.pyplot as plt

# some labels for each row
people = ('A','B','C','D','E','F','G','H')
r = len(people)

# how many data points overall (average of 3 per person)
n = r * 3

# which person does each segment belong to?
rows = np.random.randint(0, r, (n,))
# how wide is the segment?
widths = np.random.randint(3,12, n,)
# what label to put on the segment (xrange in py2.7, range for py3)
labels = range(n)
colors ='rgbwmc'

patch_handles = []

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)



left = np.zeros(r,)
row_counts = np.zeros(r,)

for (r, w, l) in zip(rows, widths, labels):
print r, w, l
patch_handles.append(ax.barh(r, w, align='center', left=left[r],
color=colors[int(row_counts[r]) % len(colors)]))
left[r] += w
row_counts[r] += 1
# we know there is only one patch but could enumerate if expanded
patch = patch_handles[-1][0]
bl = patch.get_xy()
x = 0.5*patch.get_width() + bl[0]
y = 0.5*patch.get_height() + bl[1]
ax.text(x, y, "%d%%" % (l), ha='center',va='center')

y_pos = np.arange(8)
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.set_xlabel('Distance')

plt.show()

这会生成一个像这样的图表 heterogeneous hbars ,每个系列中存在不同数量的线段。

请注意,这并不是特别有效,因为每个段都使用了对 ax.barh 的单独调用。可能有更有效的方法(例如,通过用零宽度段或 nan 值填充矩阵)但这可能是特定于问题的,并且是一个不同的问题。


编辑:已更新以回答问题的两个部分。

import numpy as np
import matplotlib.pyplot as plt

people = ('A','B','C','D','E','F','G','H')
segments = 4

# generate some multi-dimensional data & arbitrary labels
data = 3 + 10* np.random.rand(segments, len(people))
percentages = (np.random.randint(5,20, (len(people), segments)))
y_pos = np.arange(len(people))

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)

colors ='rgbwmc'
patch_handles = []
left = np.zeros(len(people)) # left alignment of data starts at zero
for i, d in enumerate(data):
patch_handles.append(ax.barh(y_pos, d,
color=colors[i%len(colors)], align='center',
left=left))
# accumulate the left-hand offsets
left += d

# go through all of the bar segments and annotate
for j in range(len(patch_handles)):
for i, patch in enumerate(patch_handles[j].get_children()):
bl = patch.get_xy()
x = 0.5*patch.get_width() + bl[0]
y = 0.5*patch.get_height() + bl[1]
ax.text(x,y, "%d%%" % (percentages[i,j]), ha='center')

ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.set_xlabel('Distance')

plt.show()

您可以按照这些路线获得结果(注意:我使用的百分比与条形宽度无关,因为示例中的关系似乎不清楚):

example output

有关堆叠水平条形图的一些想法,请参阅 Horizontal stacked bar chart in Matplotlib


关于python - 水平堆积条形图并为每个部分添加标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21397549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com