2

Installed packages

holoviews 1.14.4, geoviews 1.9.1., matplotlib 3.4.2.

What I'm trying to do

I am trying to apply simple per-feature styles using GeoViews and the matplolib backend. I cannot figure out how to apply different edgecolor= parameters to different gv.Polygons elements in the same overlay. For some reason, they're always lightblue...

Similarly, facecolor= seems to have no effect.

Reproducible code sample

This uses a very small sample of the full dataset.

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

# loading both extensions as the full script calls for user input
# to choose between an interactive or static output

gv.extension('bokeh', '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")

layout = gv.Polygons(gdf1, group="group1") * gv.Polygons(gdf2, group="group2")

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

gv.save(layout, "test.svg", dpi=600, backend='matplotlib')

Screenshot of the observed behaviour

This is a screen from the full dataset.

the red polygons belong to gdf1, the blue ones to gdf3

Expected behaviour

The red fill polygons belong to gdf1 and should have a black edgecolor but it's light blue instead. The blue fill polygon belongs to gdf2 and should have a lightblue fill and blue edgecolor, though the same color seems to be applied to both fill and edge.

What I've tried

Instead of using the group= parameter to specify styling for each of the Polygon elements (which I accidentally stumbled upon through the datashader documentation), I tried making multiple opts calls 'in-line' as suggested in the documentation for HoloViews here. This also has no effect.

Also, cmap=['color'] is the only method I've found to work to have GeoViews not use the automatically detected 'use' column in gdf1 as a vdim for color mapping. Is this the canonical approach and/or expected behaviour? color= or facecolor= seems to have no effect even though they are listed when calling gv.help(gv.opts.Polygons).

In short, I don't understand how to apply these particular styling parameters for the matplotlib backend and would very much appreciate any pointers.

2-Aug-21 Edit

Another strange behaviour seems to be that the figure in the, in my case VSCode-Python, interpreter, where the symbology seems to be faithfully represented, looks different from the .svg output generated by gv.save(layout, "test.svg", dpi=600, backend='matlplotlib'). The below images are outputs from the same run of the script.

Interpreter output:

enter image description here

gv.save() output:

enter image description here

grg
  • 99
  • 6

1 Answers1

0

May be a bug within one of the packages used. Seems to be working with these package versions on Python 3.8 (in fresh Anaconda environment created with conda create -n py38 -c pyviz -c conda-forge geoviews iris xesmf python=3.8):

  • geoviews 1.9.6
  • holoviews 1.15.4
  • matplotlib 3.7.0

Below is the svg I got when I tried your example (with linewidth=2):

two polygons with different edgecolor, third polygon omitted

prusswan
  • 6,853
  • 4
  • 40
  • 61