I am trying to plot 9 geopandas.GeoDataFrames
which are stored in a dictionary. As they share the same legend, I would like to get handles
and labels
to plot only one legend beside the maps.
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(16,6), sharex=True, sharey=True)
for eix, key in zip(axes.flat, maps.keys()):
maps[key].plot(ax=eix,
column='NAMES')
I have tried to follow this question, doing:
handles, labels = ax.get_legend_handles_labels()
fig.legend(handles, labels, bbox_to_anchor=(1.05, 1), loc='upper center')
but without success. handles
and labels
returned empty lists when I used ax.get_legend_handles_labels()
inside and outside the loop.
If I try:
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(16,6), sharex=True, sharey=True)
for eix, key in zip(axes.flat, maps.keys()):
maps[key].plot(ax=eix,
column='NAMES',
legend=True);
I get one legend for each map, but it is not what I want. So, does anyone have any suggestions?
Code example with 4 GeoDataFrames
:
import pandas as pd
import numpy as np
import geopandas as gpd
import matplotlib.pyplot as plt
### THE CODE BELOW IS JUST TO CREATE THE DICTIONARY WITH GEOPANDAS.GEODATAFRAMES
# I uploaded a geopandas dataset just to exemplify
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
#creating meaningless classes to have a dictionary with the same characteristics as my real dic
world.replace({'continent' : { 'Oceania': 'A', 'Africa': 'B', 'North America': 'C', 'Asia': 'D', 'South America': 'E',
'Europe': 'F', 'Seven seas (open ocean)': np.NaN, 'Antarctica': 'G'}}, inplace=True)
world['cont_class']=world.continent
world['pop_class']=pd.cut(world['pop_est'],
bins=[0, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000],
include_lowest=True,
labels=['A','B','C', 'D', 'E', 'F', 'G'],
right=True)
world['gdp_class']=pd.cut(world['gdp_md_est'],
bins=[0, 810, 250000, 500000, 1000000, 5000000, 20000000],
include_lowest=True,
labels=['A','B','C', 'D', 'E', 'F'],
right=True)
world['A_class']=pd.cut(world.index,
bins=7,
include_lowest=True,
labels=['A','B','C', 'D', 'E', 'F', 'G'],
right=True)
# creating the dictionary
class_names = ['cont_class', 'pop_class', 'gdp_class', 'A_class']
maps = {name: gpd.GeoDataFrame() for name in class_names}
for key in maps.keys():
maps[key]=world
maps[key]=maps[key].assign(NAMES=world[key])
### THE CODE ABOVE IS JUST TO CREATE THE DICTIONARY WITH GEOPANDAS.GEODATAFRAMES
# Question code starts here:
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(16,6), sharex=True, sharey=True)
for eix, key in zip(axes.flat, maps.keys()):
maps[key].plot(ax=eix,
column='NAMES')
handles, labels = eix.get_legend_handles_labels()
fig.legend(handles, labels, bbox_to_anchor=(1.05, 1), loc='upper center');