Why are my Matplotlib subplots sized differently?

Viewed 252

Hello there!

I am trying to create a figure consisting of a chloropleth map and a bar plot in Matplotlib. To achieve this, i am using the Geopandas library alongside Pandas and Matplotlib. I've run into an interesting problem that i couldn't find any answer for on the internet. Here's the problem:

This link leads to an image that replicates the problem.

As it can be seen on the image above, the map on the top (generated by Geopandas) does not span the same width as the bar chart on the bottom. There is too much whitespace to the left and the right of the figure. I want to get rid of this whitespace and make the map fit horizontally on the space that is allocated to it. I am also leaving a code sample below for those who wish to recreate it:

fig = plt.figure(figsize = (25.60,14.40)) #Here, i am setting the overall figure size

ax_1 = fig.add_subplot(2,1,1) #This will be the map

istanbul_districts.plot(ax = ax_1,
                    edgecolor = "black",
                    alpha = 1,
                    color = "Red") #Istanbul_districts is a GeoDataFrame object.


ax_2 = fig.add_subplot(2,1,2)


labels = list(health.loc[:,"district_eng"].value_counts().sort_values(ascending = False).index)


from numpy import arange
bar_positions = arange(len(labels)) + 1

bar_heights = h_inst_per_district_eng.loc[:,"health_count"].values.astype(int)


ax_2.bar(bar_positions,bar_heights,
    width = 0.7,
    align = "center",
    color = "blue") #This is a generic barplot from Matplotlib

I am leaving a second image that shows the end result of the code snippet above:

This link also leads to an image that replicates the problem.

It can be clearly seen above that the axes of the two subplots do not start and end on the same location. Perhaps that could be the problem? What can be done to make them the same size?

Thanks to all those answer for their time in advance!

2 Answers

Adding an explanation, since you have found one solution.

If you specify matplotlib figure with two axes in a way you did, you get the figure split in half. Both axes are the same. Let's say that the original ratio of the figure is 1:1, your axes will be both 1:2.

This arbitrary ratio is fine for a bar chart, which can be scaled to essentially any ratio. It does not matter much if it is horizontal or vertical (from a plotting perspective, not data-viz).

However, if you want your map to show correct non-distorted shapes, you can't just specify the aspect ratio. That just follows the data. So if you have a map, which bounding box has 1:1 ratio, you can't expect that it will fill the whole 1:2 axis. GeoPandas changes the aspect ratio to follow the map's ratio.

The reason why the first example leaves gaps on side and the "solution" does not is this. Because the leftover space is on top and on the bottom the axis, it is not shown in the solution. Because it is on sides in the issue, it just stays there. If you had your plots next to each other instead of above, it would be vice versa.

Hope it is clearer.

Hello again!

swatchai's comment set me up on the right track and i found the culprit. Simply adjusting the figsize to a value like (19,19) fixed the problem. I'd still be happy if anyone can explain exactly why this happens.

Here's what it looks like when the figsize is a square (19,19):

Also, here's a reproduction of what it looks like when the figsize is a square.

Thanks for your efforts!

Related