Mapping Geo Data¶
Bokeh has started adding support for working with Geographical data. There are a number of powerful features already available, but we still have more to add. Please tell use your use cases through the mailing list or on github so that we can continue to build out these features to meet your needs.
GeoJSON is a popular open standard for representing geographical features with JSON. It describes points, lines and polygons (called Patches in Bokeh) as a collection of features. Each feature can also have a set of properties.
GeoJSONDataSource can be used almost seamlessly in place of Bokeh’s
ColumnDataSource. For example:
from bokeh.io import output_file, show from bokeh.models import GeoJSONDataSource from bokeh.plotting import figure from bokeh.sampledata.sample_geojson import geojson geo_source = GeoJSONDataSource(geojson=geojson) p = figure() p.circle(x='x', y='y', alpha=0.9, source=geo_source) output_file("geojson.html") show(p)
The important thing to know is that behind the scenes, Bokeh converts the GeoJSON coordinates into columns called x and y (z where appropriate) or xs and ys depending on whether the features are Points, Lines, MultiLines, Polygons or MultiPolygons. Properties with clashing names will be overridden when the GeoJSON is converted, so the following code would not behave as expected.
If your GeoJSON properties contain a property x and you want to use this to set the size of your circles, and you do this:
Antipattern this will not work.
p.circle(size='x', alpha=0.9, source=geo_source)
You will not get the plot you expect because this is equivalent to
p.circle(x='x', y='y', size='x', alpha=0.9, source=geo_source)
and the x value from your properties will be overridden with the longitude values from your geometry coordinates.
Google Maps support¶
With the GMapPlot, you can plot any bokeh glyphs over a Google Map.
from bokeh.io import output_file, show from bokeh.models import ( GMapPlot, GMapOptions, ColumnDataSource, Circle, DataRange1d, PanTool, WheelZoomTool, BoxSelectTool ) map_options = GMapOptions(lat=30.29, lng=-97.73, map_type="roadmap", zoom=11) plot = GMapPlot( x_range=DataRange1d(), y_range=DataRange1d(), map_options=map_options ) plot.title.text = "Austin" source = ColumnDataSource( data=dict( lat=[30.29, 30.20, 30.29], lon=[-97.70, -97.74, -97.78], ) ) circle = Circle(x="lon", y="lat", size=15, fill_color="blue", fill_alpha=0.8, line_color=None) plot.add_glyph(source, circle) plot.add_tools(PanTool(), WheelZoomTool(), BoxSelectTool()) output_file("gmap_plot.html") show(plot)
There is an open issue documenting points appearing to be ~10px off from their intended location.
Google has its own terms of service for using Google Maps API and any use of Bokeh with Google Maps must be within Google’s Terms of Service
Bokeh plots can also consume XYZ tile services which use the Web Mercator projection. The module
bokeh.tile_providers contains several pre-configured tile sources with appropriate attribution which can be added to a plot using the .add_tile() method.
from bokeh.io import output_file, show from bokeh.plotting import figure from bokeh.tile_providers import STAMEN_TONER bound = 20000000 # meters fig = figure(tools='pan, wheel_zoom', x_range=(-bound, bound), y_range=(-bound, bound)) fig.axis.visible = False fig.add_tile(STAMEN_TONER) output_file("stamen_toner_plot.html") show(fig)