0

I'm new with bokeh plots and I'm trying plot a map with a slider, but it's not updating.

I've tried many ways, but it still not updating the plot.

I'm using bokeh server and non geographic plots I've got it...

what i'm doing is :

def get_dataset(dataframe,column,geometry_column,val):
    g = geodataframe[geodataframe[column] == val]
    g_gdf = gpd.GeoDataFrame(g, geometry=geometry_column)
    g_gdf.crs = 'EPSG:3857'
    return g_gdf

(this function receives a dataframe and retuns a geodataframe filtered by time value

def plot_area(geodataframe ,title_name,w ,h ,hovertool=None, tile = None, cmp_colum = None ,palette_name = None,
              cmp = False,ax =False):

from bokeh.plotting import figure
from bokeh.tile_providers import get_provider
from bokeh.models import GeoJSONDataSource,ColumnDataSource,ColorBar,BasicTicker,LinearColorMapper

poligonos = GeoJSONDataSource(geojson=geodataframe.to_json())
tile_provider = get_provider(tile)
p = figure(title=title_name,plot_width=w, plot_height=h,tooltips=hovertool)
p.add_tile(tile_provider)
p.axis.visible = ax

if cmp:
    color_mapper = LinearColorMapper(palette = palette_name , low = geodataframe[cmp_colum].min(),
                             high = geodataframe[cmp_colum].max())
    color_bar = ColorBar(color_mapper=color_mapper, ticker=BasicTicker(),location=(0,0),
                             label_standoff=12)
    
    p.patches('xs','ys', source=poligonos, fill_alpha=1, line_width=0.5, line_color='black',  
        fill_color={'field' :cmp_colum, 'transform': color_mapper})
    p.add_layout(color_bar, 'left')
else :
    pass

return p

this function plots an area.

so ...

from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.models.widgets import DataTable,Paragraph
from bokeh.layouts import row, widgetbox
from bokeh.layouts import layout
from bokeh.models.widgets import Slider
import panel as pn
from bokeh.io import curdoc
from bokeh.io import show

g = get_dataset(precipitacao_por_bacia,'datahora','st_astext',dias[0])
g.reset_index(drop=True,inplace=True)
g['datahora'] = g['datahora'].apply(lambda x: str(x))
p = plot_area(g ,'Precipitação ',w = 500 ,h = 500, hovertool=[('Bacia','@bacia_nome'),
             ('precipitação','@val')],tile = 'CARTODBPOSITRON_RETINA', cmp_colum = 'val' ,
             palette_name = 'Viridis256',cmp = True,ax =False)

def update_map(attrname, old, new):
    g = get_dataset(precipitacao_por_bacia,'datahora','st_astext',dias[slider.value])
    g.reset_index(drop=True,inplace=True)
    plot_area(g ,'Precipitação ',w = 500 ,h = 500, hovertool=[('Bacia','@bacia_nome'),
             ('precipitação','@val')],tile = 'CARTODBPOSITRON_RETINA', cmp_colum = 'val' ,
              palette_name = 'Viridis256',cmp = True,ax =False)
    g['datahora'] = g['datahora'].apply(lambda x: str(x))
    output.text= str(g['datahora'][0])

slider = Slider(title="Day", value=0, start=0, end=409)
output=Paragraph()[enter image description here][1]

slider.on_change('value', update_map)
layout = row(p,widgetbox(slider,output))
curdoc().add_root(layout)

1 Answers1

1

You are creating a new plot in your callback callback by calling plot_area but then immediately throwing it away and doing nothing to it. It needs to be added to the document in order for it to have any impact whatsoever on what is rendered in the client. Something along the lines of

def update_map(attrname, old, new):

    p = plot_area(....)

    # replace the old plot with the new one
    layout.children[0] = p
bigreddot
  • 33,642
  • 5
  • 69
  • 122