I have a geoviews map that shows points from my geopandas dataframe. I would like to use panel to create a select widget to color the map by one of the columns, as I have done with pandas dataframes and hvplot.
Example object
import random
import geopandas as gpd
import geoviews as gv
df = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))
# create some columns of random data
df['A'] = [random.randrange(1, 50, 1) for i in range(len(df))]
df['B'] = [random.randrange(200, 300, 1) for i in range(len(df))]
The code in this snippet creates a map, but the color argument is hard coded:
poly_plot = gv.Points(df).opts(color='A', width=600, height=600, colorbar=True, clabel='A',
cmap='inferno', size=12)
gv.tile_sources.OSM * poly_plot
However, when I attempt to add a widget select for the color dropdown using panel I get an error:
# create the select widget
columns = pn.widgets.Select(name='columns', options=['A', 'B'])
# create my geoviews object, specifying my select widget for color
poly_plot = gv.Points(df).opts(color=columns, width=600, height=600, colorbar=True,
clabel='A', cmap='inferno', size=12)
# plot on a basemap
gv.tile_sources.OSM * poly_plot
The error:
ValueError [Call holoviews.ipython.show_traceback() for details] failed to validate Scatter(id='p2448', ...).fill_color: expected an element of either String, Nullable(Color), Instance(Value), Instance(Field), Instance(Expr), Struct(value=Nullable(Color), transform=Instance(Transform)), Struct(field=String, transform=Instance(Transform)) or Struct(expr=Instance(Expression), transform=Instance(Transform)), got Select(name='columns', options=['A', 'B'], value='A')
The output of holoviews.ipython.show_traceback()
is long so I didn't post it, but I'm happy to add if it's helpful.
The select widget seems to get created correctly, but I can't get it connected to the plot (error above).
Thank you!
You could add the columns (A
and B
) as a dim
and make a callable to update the layout/map :
import panel as pn
from geoviews import dim, opts
def update(col):
return gv.Points(
df,
).opts(
opts.Points(
width=800,
height=500,
colorbar=True,
cmap="inferno",
size=12,
color=dim(col),
)
)
csel = pn.widgets.Select(options=["A", "B"], value="A")
@pn.depends(col=csel.param.value)
def plot(col):
return gv.tile_sources.OSM * update(col)
pn.Column(csel, plot).show()
Output (at localhost):