jan.sfr
jan.sfr

Reputation: 33

Python Geopandas: Single Legend for multiple plots

How do I use a single legend for multiple geopandas plots?

Right now I have a Figure like this:

Population Density in Germany in 2005, 2009 and 2013

This post explains how to set legend values to the same for each plot. Though, i would like to have single legend for all plots. Optimally it should be possible to have multiple legends for different df's that I want to plot. E.g. the lines you see in the pictures also have a description.

Here is my current code:

years = [2005, 2009, 2013]
    # initialize figure 
    fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(10, 10), dpi=300, constrained_layout=True)
    for i, year in enumerate(years):
        # subset lines
        lines_plot = lines[lines['year'] == year]
        # subset controls plot
        controls_plot = controls[controls['year'] == year]
        # draw subfig
        controls_plot.plot(column='pop_dens', ax=ax[i], legend=True, legend_kwds={'orientation': "horizontal"})
        lines_plot.plot(ax=ax[i], color='red', lw=2, zorder=2)

Upvotes: 1

Views: 820

Answers (1)

AlexWach
AlexWach

Reputation: 602

Regarding the first of your questions 'How do I use a single legend for multiple geopandas plots?' you could make sure your plots all use the same colors (using the vmin and vmax args of the .plot() function) and then add a single colorbar to the figure like shown below. for the red lines you can just add another legend (the first thing is technically a colorbar not a legend).

import geopandas as gpd
from matplotlib import pyplot as plt
import matplotlib.cm as cm
import matplotlib.colors as mcolors
from matplotlib.lines import Line2D

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

f, ax = plt.subplots(nrows=1, ncols=3, figsize=(9, 4))

# define min and max values and colormap for the plots
value_min = 0
value_max = 1e7
cmap = 'viridis'

world.plot(ax=ax[0], column='pop_est', vmin=value_min, vmax=value_max, cmap=cmap)
world.plot(ax=ax[1], column='pop_est', vmin=value_min, vmax=value_max, cmap=cmap)
world.plot(ax=ax[2], column='pop_est', vmin=value_min, vmax=value_max, cmap=cmap)

# define a mappable based on which the colorbar will be drawn
mappable = cm.ScalarMappable(
    norm=mcolors.Normalize(value_min, value_max),
    cmap=cmap
)

# define position and extent of colorbar
cb_ax = f.add_axes([0.1, 0.1, 0.8, 0.05])

# draw colorbar
cbar = f.colorbar(mappable, cax=cb_ax, orientation='horizontal')

# add handles for the legend
custom_lines = [
    Line2D([0], [0], color='r'),
    Line2D([0], [0], color='b'),
]

# define labels for the legend
custom_labels = ['red line', 'blue line']

# plot legend, loc defines the location
plt.legend(
    handles=custom_lines,
    labels=custom_labels,
    loc=(.4, 1.5),
    title='2nd legend',
    ncol=2
)
plt.tight_layout()
plt.show()

enter image description here

Upvotes: 1

Related Questions