Search code examples
pythonbokeh

bokeh This page didn’t load Google Maps correctly


When I use bokeh to plot Google Map, it shows this problem "Oops! Something went wrong.This page didn’t load Google Maps correctly. See the JavaScript console for technical details.". I have used my newest Google Map API, dont know what is going on.

from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, GMapOptions
from bokeh.plotting import gmap
output_file("gmap.html")
map_options = GMapOptions(lat=30.2861, lng=-97.7394, map_type="roadmap", zoom=11)
p = gmap("AIzaSyCEjCcXedjs80NSWbsU2WdURkK7ncG8rYo", map_options, title="Austin")

source = ColumnDataSource(
    data=dict(lat=[ 30.29,  30.20,  30.29],
              lon=[-97.70, -97.74, -97.78])
)
p.circle(x="lon", y="lat", size=15, fill_color="blue", fill_alpha=0.8, source=source)
show(p)

enter image description here


Solution

  • You are getting an ApiNotActivatedMapError. This is because you are not using a valid google api key. In the error message you can find a link to an introduction of how to get an api key.

    But there is also another option using bokeh with OpenStreetMaps which will give you this nice map with three circles. This will avoid the problem you had.

    Openstreetmap of Austin with three circles.

    To make this work you need to use CARTODBPOSITRON and get_provider from bokeh.tile_providers.

    Code

    import numpy as np
    
    from bokeh.plotting import figure, output_file, show
    from bokeh.tile_providers import CARTODBPOSITRON, get_provider
    
    output_file("gmap.html")
    
    # helper function for coordinate conversion between lat/lon in decimal degrees to web mercator
    def lnglat_to_meters(longitude, latitude):
        """
        Projects the given (longitude, latitude) values into Web Mercator
        coordinates (meters East of Greenwich and meters North of the Equator).
        """
        origin_shift = np.pi * 6378137
        easting = longitude * origin_shift / 180.0
        northing = np.log(np.tan((90 + latitude) * np.pi / 360.0)) * origin_shift / np.pi
        return (easting, northing)
    
    tile_provider = get_provider(CARTODBPOSITRON)
    
    # Lady Bird Lake, Austin Texas
    lat = 30.268801
    lon = -97.763347
    
    EN = lnglat_to_meters(lon, lat)
    dE = 10000 # (m) Easting  plus-and-minus from map center
    dN = 5000 # (m) Northing plus-and-minus from map center
    
    x_range = (EN[0]-dE, EN[0]+dE) # (m) Easting  x_lo, x_hi
    y_range = (EN[1]-dN, EN[1]+dN) # (m) Northing y_lo, y_hi
    
    # range bounds supplied in web mercator coordinates
    p = figure(x_range=x_range, y_range=y_range,
               x_axis_type="mercator", y_axis_type="mercator")
    p.add_tile(tile_provider)
    
    # circles
    source = {'north':[], 'east':[]}
    for a, b in zip([-97.70, -97.74, -97.78], [ 30.29,  30.20,  30.29]):
        ans = lnglat_to_meters(a, b)
        source['north'].append(ans[1])
        source['east'].append(ans[0])
    
    source = ColumnDataSource(data=source)
    p.circle(x="east", y="north", size=15, fill_color="blue", fill_alpha=0.8, source=source)
    
    show(p)
    

    Comment

    The solution above is inspired by the tile_demo you can find in the bokeh github project.