Ich werde dies in zwei Teile geteilt:
Ich frage mich, was die Einheit der Höhe in barh ist
(Offenbar haben die Menschen dieses since 2009 fragen ... also denke ich, Sie sind in guter Gesellschaft!)
Diese Frage ist der leichtere Teil - es ist ein Prozentsatz der Höhe, die der Leiste in der Abbildung zugewiesen ist. Der Standardwert height=0.8
bedeutet beispielsweise, dass die Höhe des Balkens 0.8 * (plot_height/n_bars)
ist. Sie können dies sehen, indem Sie height=1.0
einstellen (oder sogar einen Wert> 1, die Balken überlappen sich). Wenn Sie wirklich sicher sein wollen, hier ist die source of axes.barh
. Dies erfordert nur axes.bar
- werfen Sie einen Blick auf these lines:
nbars = len(bottom)
if len(left) == 1:
left *= nbars
if len(height) == 1:
height *= nbars
Und later on ...
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)
So sehen Sie die Höhe von nbars
skaliert wird, und wenn Sie das Rechteck zeichnen sind sie gestaffelt durch diese Höhe.
wie es
fixiert machen Das ist härter, werden Sie es manuell einstellen müssen. Die Balken auf dem Diagramm sind letztlich matplotlib.patches.Rectangle
Objekte, die eine Breite und Höhe haben ... was auch ein Prozentsatz ist. Ich denke, die beste Lösung besteht darin, den entsprechenden Prozentsatz manuell zu berechnen.
Hier ist ein kurzes Beispiel, basierend aus einem 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()
Teil A pixel_h/current_h
berechnet eine Umwandlung zwischen den Pixeln und Höheneinheiten zu erhalten. Dann können wir desired_h
(Pixel) durch dieses Verhältnis teilen, um desired_h
in Höheneinheiten zu erhalten. Dadurch wird die Balkenbreite auf 5 px festgelegt, aber der untere Rand des Balkens bleibt an derselben Stelle, sodass er nicht mehr mit den Beschriftungen und Fehlerbalken ausgerichtet ist.
Teil B berechnet die neue y-Position. Da y
und height
in den gleichen Einheiten sind, können wir einfach die Hälfte des Höhenunterschieds hinzufügen (y_diff
), um die neue Position zu erhalten. Dadurch bleibt der Balken in der ursprünglichen y-Position zentriert.
Beachten Sie, dass dies nur die anfängliche Größe festlegt. Wenn Sie beispielsweise die Größe des Diagramms ändern, skalieren die Balken weiterhin - Sie müssten dieses Ereignis überschreiben, um die Größe der Balken entsprechend anzupassen.
Es ist erstaunlich, dass es keine einfache Möglichkeit gibt, eine feste Höhe einzustellen. –