Reputation: 16620
I have several different barplot figures to generate with a varying amount of bars. The total width and height of the figure thus varies, but I would like the bars to be consistently sized the same for all barplots.
What I tried so far is to resize the figsize proportionally to the number of bars. This does not seem to work consistently.
Here is a sample code:
nb_bars_list = [2, 10]
for i, nb_bars in enumerate(nb_bars_list):
# Resize proportionally to the number of bars
figsize = [1+nb_bars, 5]
# Prepare the ticks
ticks = np.arange(1, 1+nb_bars, 1)
# Generate random points
points = [np.random.randn(10) for x in xrange(nb_bars)]
# Make the plot
fig, ax = plt.subplots()
if figsize:
fig.set_size_inches(figsize[0], figsize[1], forward=True)
for b in xrange(nb_bars):
ax.bar(ticks[b], points[b].mean())
fig.savefig('test%i' % i, bbox_inches='tight')
If we overlap both using GIMP, we can clearly notice the difference in bar widths:
How can I ensure the same width for the bars, whatever the number of bars?
I am using matplotlib 2.
Upvotes: 4
Views: 932
Reputation: 339660
To set the figure size such that different numbers of bars in a figure always have the same width would require to take the figure margins into account. Also one would need to set the xlimits of the plot equally in all cases.
import matplotlib.pyplot as plt
import numpy as np
nb_bars_list = [2, 10]
margleft = 0.8 # inch
margright= 0.64 # inch
barwidth = 0.5 # inch
for i, nb_bars in enumerate(nb_bars_list):
# Resize proportionally to the number of bars
axwidth = nb_bars*barwidth # inch
figsize = [margleft+axwidth+margright, 5]
# Prepare the ticks
ticks = np.arange(1, 1+nb_bars, 1)
# Generate random points
points = [np.random.randn(10) for x in xrange(nb_bars)]
# Make the plot
fig, ax = plt.subplots(figsize=figsize)
fig.subplots_adjust(left=margleft/figsize[0], right=1-margright/figsize[0])
for b in xrange(nb_bars):
ax.bar(ticks[b], points[b].mean())
ax.set_xlim(ticks[0]-0.5,ticks[-1]+0.5)
#fig.savefig('test%i' % i, bbox_inches='tight')
plt.show()
Upvotes: 6