Reputation: 417
I've got a notebook (github link) where I'm using geopandas to draw maps with various countries colored. Depending on the order of the plots, sometimes it doesn't respect the figsize() I specify. I'm seeing this behavior repeatably in jupyter running locally in Ubuntu 20.04 and Firefox, and both Binder and Colab running in Chromium.
Can somebody help me understand what's going on? Is this a bug or am I controlling geopandas/matplotlib wrong?
import matplotlib.pyplot as plt
import geopandas as gpd
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
sixc = world[ world['continent'] != 'Antarctica' ]
asia = world[ world['continent'] == 'Asia' ]
noam = world[ world['continent'] == 'North America']
swed = world[ world['iso_a3'] == 'SWE' ]
# This works, makes a 2x1 landscapey aspect
axes = sixc.plot(figsize=(8,4), color='lightgrey')
asia.plot(ax=axes, color='green')
noam.plot(ax=axes, color='purple')
# Plotting swed at the end breaks figsize, makes it squareish
axes = sixc.plot(figsize=(8,4), color='lightgrey')
asia.plot(ax=axes, color='green')
noam.plot(ax=axes, color='purple')
swed.plot(ax=axes, color='yellow')
# Plotting swed in the middle makes it ok again
axes = sixc.plot(figsize=(8,4), color='lightgrey')
asia.plot(ax=axes, color='green')
swed.plot(ax=axes, color='yellow')
noam.plot(ax=axes, color='purple')
(Also, for some (but not all!) of my students, that broken plot also has no lightgray background countries. Is that likely a result/side-effect of whatever is causing the aspect problem?)
Upvotes: 3
Views: 775
Reputation: 18782
With geopandas
v 0.8.1 you are using, the default
aspect ratio of the plot commands you use is auto
. Thus, the output plots you obtained will have unpredictable value of aspect ratio. Try
print(axes.get_aspect())
for each plot. In previous version of geopandas, one will get equal
as output, and the plots are correct. But in your case, you will get values that do not represent equal aspect.
For a simple fix of your problem, you can add this line of code:
axes.set_aspect('equal')
after the last plot statement.
Upvotes: 6
Reputation: 16683
This is a great answer regarding how aspect ratio works in matplotlib
; however, although the concepts are helpful, GeoSeries.plot
is built on top of matplotlib, so that answer might not help in terms of the code that would solve the problem.
The easiest thing to do is to pass aspect='equal'
to each GeoSeries.plot
as default is 'auto'
for "aspect" in link).
As for your other issue, I cannot reproduce, and I would have those students upgrade to the latest versions or use a different IDE. This works for me in a Jupyter Notebook.
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
sixc = world[ world['continent'] != 'Antarctica' ]
asia = world[ world['continent'] == 'Asia' ]
noam = world[ world['continent'] == 'North America']
swed = world[ world['iso_a3'] == 'SWE' ]
# This works, makes a 2x1 landscapey aspect
axes = sixc.plot(figsize=(8,4), color='lightgrey', aspect='equal')
asia.plot(ax=axes, color='green', aspect='equal')
noam.plot(ax=axes, color='purple', aspect='equal')
# Plotting swed at the end breaks figsize, makes it squareish
axes = sixc.plot(figsize=(8,4), color='lightgrey', aspect='equal')
asia.plot(ax=axes, color='green', aspect='equal')
noam.plot(ax=axes, color='purple', aspect='equal')
swed.plot(ax=axes, color='yellow', aspect='equal')
# Plotting swed in the middle makes it ok again
axes = sixc.plot(figsize=(8,4), color='lightgrey', aspect='equal')
asia.plot(ax=axes, color='green', aspect='equal')
swed.plot(ax=axes, color='yellow', aspect='equal')
noam.plot(ax=axes, color='purple', aspect='equal')
Also, as a sidenote that dataset has some irregularities with 99
as the ISO
code. I believe it is getting fixed in an update (see https://github.com/geopandas/geopandas/issues/1041).... you can use the below code to fix them manually:
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
world.loc[world['name'] == 'France', 'iso_a3'] = 'FRA'
world.loc[world['name'] == 'Norway', 'iso_a3'] = 'NOR'
world.loc[world['name'] == 'Somaliland', 'iso_a3'] = 'SOM'
world.loc[world['name'] == 'Kosovo', 'iso_a3'] = 'RKS'
Upvotes: 1