Dante van der Heijden
Dante van der Heijden

Reputation: 97

Legend in geopandas plot for color as well as for markersize

I am creating a geopandas plot in which I have colors dependent on a column value and the markersize on another column value. When I put legend= True the plot only shows the colors in the legend and not the values of the markersize. Anyone knows how this can be added.

see my code:

fig, ax = plt.subplots(1, 1, figsize= (20, 20))

regions_un = np.unique(region)
color = {}

for i in range(len(regions_un)):
    color[regions_un[i]] = '#%06X' % randint(i, 0xFFF)
    
df_deltas_cities['color'] = df_deltas_cities['region'].map(color)

df_deltas_cities.loc[df_deltas_cities["R"] < 0, "R"] = 0
df_deltas_cities['markersize'] = df_deltas_cities['R']**2

world.plot(ax= ax, color= 'lightgrey');
df_deltas_cities.plot(column= 'region', ax=ax, markersize= 'markersize', c = df_deltas_cities['color'], legend= True);

And the resulting figure: enter image description here

What I want to be added to the legend is something like this: enter image description here

Regards,

Dante

Upvotes: 1

Views: 2522

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31146

  • made code runnable by reusing inbuilt geopandas sample geometry
  • you can add a second legend where marker size is scaled to numeric values found in your data frame
import matplotlib.pyplot as plt
import geopandas as gpd
import numpy as np
import matplotlib.lines as mlines
import pandas as pd

world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
df_deltas_cities = gpd.read_file(gpd.datasets.get_path("naturalearth_cities"))
df_deltas_cities["region"] = np.random.choice(
    ["Cities", "Deltas", "Cities+Deltas"], len(df_deltas_cities)
)

df_deltas_cities["markersize"] = np.random.uniform(5, 400, len(df_deltas_cities))
df_deltas_cities["color"] = df_deltas_cities["region"].map(
    {a: b for a, b in zip(df_deltas_cities["region"].unique(), "rgb")}
)
fig, ax = plt.subplots(1, 1, figsize=(8, 8))

ax = world.plot(ax=ax, color="lightgrey")
ax = df_deltas_cities.plot(
    column="region",
    ax=ax,
    markersize="markersize",
    c=df_deltas_cities["color"],
    legend=True,
)

# need to add existing legend back
leg1 = ax.get_legend()

# some bins to indicate size in legend
_, bins = pd.cut(df_deltas_cities["markersize"], bins=3, precision=0, retbins=True)
# create second legend
ax.add_artist(
    ax.legend(
        handles=[
            mlines.Line2D(
                [],
                [],
                color="black",
                lw=0,
                marker="o",
                markersize=np.sqrt(b),
                label=str(int(b)),
            )
            for i, b in enumerate(bins)
        ],
        loc=4,
    )
)
# restore original legend
ax.add_artist(leg1)

enter image description here

Upvotes: 1

Related Questions