Search code examples
matplotliblegendgeopandasshapefilecontextily

How to change the position of legend in a map?


I've been trying to plot a shapefile over a basemap. My issue here is the placement of the legend. I wanted it to be placed outside (next to) the map.

Specifically, I am plotting the "Ecoregion" column of the shapefile which basically labels each polygon with a colour (I figured this was better than actually putting the names on each polygon). I've tried the following code and receive an error:

pip install geopandas
pip install contextily
import geopandas as gpd
import contextily as ctx
data = gpd.read_file("icemap.shp")
plt.rcParams.update({'font.size': 14})
ax = data.plot(
    figsize=(12, 10),
    column="Ecoregion",
    cmap="tab10",
    )
map = Basemap(
    llcrnrlon=-50,
    llcrnrlat=30,
    urcrnrlon=70.0,
    urcrnrlat=85.0,
    resolution="i",
    lat_0=39.5,
    lon_0=1,
)
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
map.fillcontinents(color="lightgreen")
map.drawcoastlines()
map.drawparallels(np.arange(10,90,20),labels=[1,1,1,1])
map.drawmeridians(np.arange(-180,180,30),labels=[1,1,0,1])
plt.title("Map", fontsize=16)

The error is -

WARNING:matplotlib.legend:No handles with labels found to put in legend.

So I tried adding

legend-True

in the "ax" parentheses and removed the "ax.legend(...)", but then the legend appears on top of the map as the picture below.

enter image description here

Does "handle" refer to the column that is plotted? If so, I'm confused as to why I get this error. Or do I need to add another line of code?

I'd be grateful to receive some help in this.
(Attached file link: https://drive.google.com/file/d/1OfOAstBbbxiqSybpl_CQf-o47YgpbY7D/view?usp=sharing)


Solution

  • I would also consider Cartopy, since Basemap has been end-of-life for a long time. The resolution of your vector is also well beyond what's plotted on screen, so you could really increase performance by simplifying it a little.

    But you can pass the legend keywords along when plotting the Geodataframe.

    ax = data.plot(
        figsize=(10, 8),
        column="Ecoregion",
        cmap="tab10",
        legend=True,
        legend_kwds=dict(bbox_to_anchor=(1.05, 1), loc='upper left'),
    )
    

    enter image description here