@andhuang what have you attempted? There are lots of examples of CustomJS and even specifically sliders with CustomJS callbacks in the docs and examples repo. Have you tried to emulate any of those? If so please share the code and describe the problems you encountered.
import requests
from bokeh.models import Select, CustomJS
from bokeh.models.tiles import BBoxTileSource
from bokeh.plotting import figure
from bokeh.tile_providers import get_provider, Vendors
from bokeh.io import notebook, show
from bokeh.layouts import Row
p = figure(x_range=(-2000000, 4000000), y_range=(-1000000, 7000000),
x_axis_type="mercator", y_axis_type="mercator")
time_stops = requests.get("https://nowcoast.noaa.gov/layerinfo?request=timestops&service=analysis_meteohydro_sfc_rtma_time&layers=7&format=json").json()["layers"][0]["timeStops"]
url = "https://nowcoast.noaa.gov/arcgis/rest/services/nowcoast/analysis_meteohydro_sfc_rtma_time/MapServer/export?transparent=true&format=png8&layers=show%3A7&bboxSR=3857&imageSR=3857&size=256,256&f=image&time={TIME}&bbox={XMIN},{YMIN},{XMAX},{YMAX}"
tile = BBoxTileSource(url=url, extra_url_vars={"TIME": str(time_stops[0])})
select = Select(options=list(map(str, time_stops)))
callback = CustomJS(args=dict(source=tile), code="""
var time = cb_obj.value
console.log(source.extra_url_vars)
source.extra_url_vars = {"TIME": time}
source.change.emit();
""")
select.js_on_change('value', callback)
p.add_tile(tile)
layout = Row(select, p)
show(layout)
Is there a way to prevent it from flickering / flashing white between changes, e.g. finish loading the data then display rather than clearing the canvas, wait for data to load, then display? Ideally, it would look something like Forecast Models - Tropical Tidbits (press left right arrow keys). Or how do I make {TIME} act like {XMIN},{YMIN}, etc (show a pixelated version until data arrives)
@andhuang that looks roughly correct (tho naming the tile renderer “source” is a little confusing). Is there documentation on the expected URL format? When I try your code and look in the browser network pane, I see requests like
which just show blank white images when I load them. Is this actually the right format for the URLs? (i.e. are those the correct units for the timestamp?)
Is there a way to prevent it from flickering / flashing white between changes, e.g. finish loading the data then display rather than clearing the canvas, wait for data to load, then display?
The tile renderer is currently fairly simplistic. If the tile server responses are slow, then AFAIK there are not currently any mitigations on the Bokeh side, e.g. progressive refinement. There is a large grant proposal out regarding making GIS related improvements to Bokeh, that we will possibly hear good news about soon.
@andhuang I see now. I don’t think there is anything to be done about the flicker when changing time stamps. IIRC, for the geo coords, the tile renderer does keep an internal cache of tiles surrounding the current view (both in space an resolution) which helps keep transitions smooth. But the caching does not know anything about the extra URL params. Changing them requires loading in an entirely new set of tiles at once, hence the “flicker”. Caching for the geo part of tiles seems reasonable because assumptions can be made about how transitions will occur. I don’t think it would be possible to extend caching to arbitrary user-supplied parameters that can jump around randomly (i.e. you would have to “cache” sets of every possibility, all the time)
if there’s some way I can help with that, please let me know!
We are still just waiting to hear the results of the application, hopefully in the next month or so. If the proposal is funded I am sure it would be useful to have users participate in discussions and trying out changes.
I have to be honest and say this seems unlikely. It’s not a standard tile service input, and there is no way to assume up front what the acceptable timesteps and values are for a specific given service. Even more difficult, while the standard patterns of panning and zooming mean that the tile source can assume what “nearby” tiles are needed to cache, it seems like timestamps could jump rather arbitrarily since they might come from a slider, but just as easily could come from a dropdown or a buttons that just correspond to any set of arbitrary timestamps at all. The page would have to cache everything which is not really a cache, it’s just duplicating all the data in the browser. In general that would use a prohibitive amount of memory.
I think you could probably use the existing implementation as a basis, or possibly even subclass from it to specialize it. I do think level of effort would be required, though, in order to bake-in the appropriate assumptions (that are specific and unique to our use-case) about how caching along the time dimension should be done. You can find information about creating Bokeh custom extensions here: