2

Installed packages

geoviews 1.9.1., matplotlib 3.4.2.

What I'm trying to do

For the Bokeh backend adding a categorical legend via GeoViews is done through proxy artists, as describe in the Katrina track example, and I managed to get this to work, but how does this work for the Matplotlib backend? The corresponding mpl example for the Katrina track case, notably does not include a legend. The other mpl examples with legends all use colorbars.

The HoloViews legend example suggests that this is done automatically, so I figured the same would apply for GeoViews but when trying to repro the example with GeoDataFrames as inputs to gv.Polygons, no legend appears.

Reproducible example

import pandas as pd
import geopandas as gpd
import geoviews as gv
from geoviews import opts

gv.extension('matplotlib')

d1 = {'use': {0: 'Residential', 1: 'Residential'},
'geometry': {0: 'POLYGON ((13.80961103741604 51.04076975651729, 13.80965521888065 51.04079016168103, 13.80963851766593 51.04080454197601, 13.80959433642561 51.04078412781548, 13.80961103741604 51.04076975651729))',
1: 'POLYGON ((13.80977831740752 51.04313480566009, 13.80987122363639 51.04306085051974, 13.8099989591537 51.04312462457182, 13.80995486494384 51.04315973323087, 13.8099651184249 51.04316486464228, 13.80991634926543 51.04320371166482, 13.80977831740752 51.04313480566009))'}}

gdf1 = gpd.GeoDataFrame(pd.DataFrame(d1), geometry=gpd.GeoSeries.from_wkt(pd.DataFrame(d1)['geometry']), crs="EPSG:4326")

d2 = {'geometry': {1: 'POLYGON ((13.80894179055831 51.04544128170094, 13.80952887156242 51.0450399782091, 13.80954152432486 51.04504668985658, 13.80896834397535 51.04545611172818, 13.80894179055831 51.04544128170094))'}}

gdf2 = gpd.GeoDataFrame(pd.DataFrame(d2), geometry=gpd.GeoSeries.from_wkt(pd.DataFrame(d2)['geometry']), crs="EPSG:4326")


feature1 = gv.Polygons(gdf1, group="group1", label='label1')
feature2 = gv.Polygons(gdf2, group="group2", label='label2')

layout = feature1.opts(color='red') * feature2.opts(color='lightgrey')

layout.opts(
            opts.Polygons('group1', cmap=['red'], edgecolor='black', linewidth=0.5, xaxis=None, yaxis=None),
            opts.Polygons('group2', cmap=['lightblue'], edgecolor='blue', linewidth=0.5),
            opts.Overlay(fig_size=500)
        )
        
gv.output(layout)

Any pointers would be appreciated (also, if possible, on an earlier related SO question of mine from a couple of weeks ago).

grg
  • 99
  • 6

1 Answers1

0

It is likely due to this known issue still outstanding: https://github.com/holoviz/geoviews/issues/450

Both your example and the one in the linked issue leads to this error:

File ~\.conda\envs\py38\lib\site-packages\matplotlib\legend_handler.py:768, in HandlerTuple.create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans)
    766 for handle1 in orig_handle:
    767     handler = legend.get_legend_handler(handler_map, handle1)
--> 768     _a_list = handler.create_artists(
    769         legend, handle1,
    770         next(xds_cycle), ydescent, width, height, fontsize, trans)
    771     a_list.extend(_a_list)
    773 return a_list

AttributeError: 'NoneType' object has no attribute 'create_artists'
prusswan
  • 6,853
  • 4
  • 40
  • 61