我将其分为两部分:
I wonder what is the unit of the height in barh
(显然人们一直想知道这个since 2009 ……所以我猜你的公司很好!)
这个问题是更容易的部分 – 它是分配给图中条形图的高度的百分比.例如,默认高度= 0.8表示条形的高度为0.8 *(plot_height / n_bars).您可以通过设置height = 1.0(或者甚至值> 1,条形将重叠)来看到这一点.
如果你真的想确定,这里是source of axes.barh.这只是调用axes.bar – 看看these lines:
nbars = len(bottom)
if len(left) == 1:
left *= nbars
if len(height) == 1:
height *= nbars
args = zip(left, bottom, width, height, color, edgecolor, linewidth)
for l, b, w, h, c, e, lw in args:
if h < 0:
b += h
h = abs(h)
if w < 0:
l += w
w = abs(w)
r = mpatches.Rectangle(
xy=(l, b), width=w, height=h,
facecolor=c,
edgecolor=e,
linewidth=lw,
label='_nolegend_',
margins=margins
)
r.update(kwargs)
r.get_path()._interpolation_steps = 100
#print r.get_label(), label, 'label' in kwargs
self.add_patch(r)
patches.append(r)
因此,您可以看到高度按nbars缩放,当您绘制矩形时,它们会以此高度间隔开.
how to make it fixed
这更难,你必须手动设置它.图表上的条形图最终是matplotlib.patches.Rectangle对象,它们具有宽度和高度……也是一个百分比.我认为最好的解决方案是手动计算适当的百分比.
这是一个基于barh demo的简短示例:
import matplotlib.pyplot as plt
plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt
# Example data
people = ('Tom', 'Dick', 'Harry', 'Slim', 'Jim')
y_pos = np.arange(len(people))
performance = 3 + 10 * np.random.rand(len(people))
error = np.random.rand(len(people))
plt.figure(figsize=(5,5), dpi=80)
myplot = plt.barh(y_pos, performance, height=0.8, xerr=error, align='center', alpha=0.4)
plt.yticks(y_pos, people)
plt.xlabel('Performance')
plt.title('How fast do you want to go today?')
for obj in myplot:
# Let's say we want to set height of bars to always 5px..
desired_h = 5
current_h = obj.get_height()
current_y = obj.get_y()
pixel_h = obj.get_verts()[2][1] - obj.get_verts()[0][1]
print("current position = ", current_y)
print("current pixel height = ", pixel_h)
# (A) Use ratio of pixels to height-units to calculate desired height
h = desired_h / (pixel_h/current_h)
obj.set_height(h)
pixel_h = obj.get_verts()[2][1] - obj.get_verts()[0][1]
print("now pixel height = ", pixel_h)
# (B) Move the rectangle so it still aligns with labels and error bars
y_diff = current_h - h # height is same units as y
new_y = current_y + y_diff/2
obj.set_y(new_y)
print("now position = ", obj.get_y())
plt.show()
A部分计算pixel_h / current_h以获得像素和高度单位之间的转换.然后我们可以将desired_h(像素)除以该比率,以获得高度单位的desired_h.这会将条形宽度设置为5像素,但条形图的底部保持在同一位置,因此它不再与标签和误差条对齐.
B部分计算新的y位置.由于y和高度是相同的单位,我们可以添加一半的高度差(y_diff)来获得新的位置.这使得栏杆以其所具有的任何原始y位置为中心.
请注意,这仅设置初始大小.例如,如果您调整绘图的大小,条形图仍将缩放 – 您必须覆盖该事件以适当调整条形图的大小.