Question

I just created a horizontal stacked bar chart using matplotlib, and I can't figure out why there is extra space between the x axis and the first bar (code and picture below). Any suggestions or questions? Thanks!

Code:

fig = figure(facecolor="white")
ax1 = fig.add_subplot(111, axisbg="white")
heights = .43
data = np.array([source['loan1'],source['loan2'],source['loan3']])
dat2 = np.array(source2)
ind=np.arange(N)
left = np.vstack((np.zeros((data.shape[1],), dtype=data.dtype), np.cumsum(data, axis=0) [:-1]))
colors = ( '#27A545', '#7D3CBD', '#C72121')

for dat, col, lefts, pname2 in zip(data, colors, left, pname):
    ax1.barh(ind+(heights/2), dat, color=col, left=lefts, height = heights, align='center', alpha = .5)

p4 = ax1.barh(ind-(heights/2), dat2, height=heights, color = "#C6C6C6", align='center', alpha = .7)

ax1.spines['right'].set_visible(False)
ax1.yaxis.set_ticks_position('left')
ax1.spines['top'].set_visible(False)
ax1.xaxis.set_ticks_position('bottom')
yticks([z for z in range(N)], namelist)

#mostly for the legend
params = {'legend.fontsize': 8}
rcParams.update(params)
box = ax1.get_position()
ax1.set_position([box.x0, box.y0 + box.height * 0.1, box.width, box.height * 0.9])
l = ax1.legend(loc = 'upper center', bbox_to_anchor=(0.5,-0.05), fancybox=True, shadow = True, ncol = 4)

show()

enter image description here

Was it helpful?

Solution

This is because matplotlib tries to intelligently choose minimum and maximum limits for the plot (i.e. "round-ish" numbers) by default.

This makes a lot of sense for some plots, but not for others.

To disable it, just do ax.axis('tight') to snap the data limits to the strict extents of the data.

If you want a bit of padding despite the "tight" bounds on the axes limits, use ax.margins.

In your case, you'd probably want something like:

# 5% padding on the y-axis and none on the x-axis
ax.margins(0, 0.05)

# Snap to data limits (with padding specified above)
ax.axis('tight')

Also, if you want to set the extents manually, you can just do

ax.axis([xmin, xmax, ymin, ymax])` 

or use set_xlim, set_ylim, or even

ax.set(xlim=[xmin, xmax], ylim=[ymin, ymax], title='blah', xlabel='etc')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top