Reputation: 483
I'm trying to adapt the following strategy (taken from here) to adjust the sizes of bars in matplotlib barplots
# Iterate over bars
for container in ax.containers:
# Each bar has a Rectangle element as child
for i,child in enumerate(container.get_children()):
# Reset the lower left point of each bar so that bar is centered
child.set_y(child.get_y()- 0.125 + 0.5-hs[i]/2)
# Attribute height to each Recatangle according to country's size
plt.setp(child, height=hs[i])
but have encountered a strange behaviour when using this on a plot based on a two-columns DataFrame. The relevant part of the code is almost identical:
for container in axes.containers:
for size, child in zip(sizes, container.get_children()):
child.set_x(child.get_x()- 0.50 + 0.5-size/2)
plt.setp(child, width=size)
The effect I get is that the size of the width of the bars (I'm using in in bar-chart; not an hbar) is changed as intended, but that the re-centering is only applied to the bars that correspond to the second column of the DataFrame (I've swapped them to check), which corresponds to the lighter blue in the figure below.
I don't quite see how this could happen, since both changes seem to be applied as part of the same loop. I also find it difficult to trouble-shoot since in my case the outer-loop goes through two containers, and the inner-loop goes through as many children as there are bars (and this for each container).
How could I start troubleshooting this? And how could I find out what I'm actually looping through? (I know each child is a rectangle-object, but this doesn't yet tell me the difference between the rectangles in both containers)
Upvotes: 2
Views: 3423
Reputation: 483
Apparently the following approach works better when modifying vertical bar-plots:
for container in axes.containers:
for i, child in enumerate(container.get_children()):
child.set_x(df.index[i] - sizes[i]/2)
plt.setp(child, width=sizes[i])
So the main difference with the original approach I was adapting is that I do not get the current x_position of the container, but re-use the index of the DataFrame to set the x_position of the container at the index minus half of its new width.
Upvotes: 1