Sorry I have been a bit slow responding to this as I haven’t used bokeh directly before and realized would need to do some research to create the cut-down example. Anyhow was much simpler than I expected. It turns out, I think bokeh does indeed wait for the tiles before rendering on export_png.
With some very simple code like below (I couldn’t find a way to use the wikimedia in bokeh, so maybe this is related to that also) I see that it basically always exports the full image except once where it displayed the following error:
WARNING:bokeh.io.export:The webdriver raised a TimeoutException while waiting for a ‘bokeh:idle’ event to signify that the layout has rendered. Something may have gone wrong.
So it looks like it does wait for export, but on timeout skips with an exception. I guess the feature to request is to retry tile on failure instead of skipping it.
from bokeh.plotting import figure
from bokeh.tile_providers import Vendors, get_provider
from bokeh.io import export_png
tile_provider = get_provider(Vendors.CARTODBPOSITRON_RETINA)
p = figure(x_range=(16793809.66, 16794508.82), y_range=(-4095373.46, -4093791.58), x_axis_type="mercator", y_axis_type="mercator")
p.add_tile(tile_provider)
export_png(p, filename="plot.png")
The cutdown version in holoviews is:
import numpy.random
import datashader.geo
import holoviews
import time
# Configure the default renderer
holoviews.extension('bokeh')
renderer = holoviews.renderer('bokeh').instance(mode='server')
# Using longitude/latitude in WGS84 format
lon_min, lat_min = (150.86135898475558, -34.49433199671786)
lon_max, lat_max = (150.8676395946077, -34.482619315846264)
# Convert to northings/eastings in meters required to match the Tiles for overlay
left, bottom = datashader.geo.lnglat_to_meters(lon_min, lat_min)
right, top = datashader.geo.lnglat_to_meters(lon_max, lat_max)
tiles = holoviews.Tiles('https://maps.wikimedia.org/osm-intl/{Z}/{X}/{Y}@2x.png', name="Wikipedia")
tiles = tiles.opts(width=600, height=550)
# Adjust the framing of the tile to show the frame and not the entire world
# From: https://examples.pyviz.org/nyc_taxi/nyc_taxi.html
x_dim = holoviews.Dimension(
'x',
label='Longitude',
range=(left, right)
)
y_dim = holoviews.Dimension(
'y',
label='Latitude',
range=(bottom, top)
)
tiles = tiles.redim(x=x_dim, y=y_dim)
#time.sleep(10)
holoviews.save(tiles, 'tiles.png')