#!/usr/bin/env python # coding: utf-8 # # # # # #
# # # # #

Bokeh 教程

#
# #

09. 地理图

# In[1]: from bokeh.io import output_notebook, show output_notebook() # 将数据集与真实世界上下文联系起来非常有用。你可以像任何其他类型的数据一样绘制地理数据,例如 [Texas Unemployment example](https://bokeh.pydata.org/en/latest/docs/gallery/texas.html) 的例子。但Bokeh提供了一些在地理坐标绘图的专门机制: # # * [GMapPlot](https://bokeh.pydata.org/en/latest/docs/user_guide/geo.html#google-maps-support): Bokeh 基于 Google Maps 绘图 # # * [TileSource](https://bokeh.pydata.org/en/latest/docs/user_guide/geo.html#tile-providers), 特别是wmtstilesource:允许数据被覆盖于任何地图平铺显示服务器和自定义服务器的数据上,包括: # [Google Maps](http://maps.google.com), # [Stamen](http://maps.stamen.com), # [MapQuest](https://www.mapquest.com/), # [OpenStreetMap](https://www.openstreetmap.org), # [ESRI](http://www.esri.com), # # * [GeoJSONDataSource](https://bokeh.pydata.org/en/dev/docs/user_guide/geo.html#geojson-datasource): 可使 [GeoJSON](http://geojson.org/) 类型数据用于Bokeh绘图,就像 `ColumnDataSource` 类型。 # ## WMTS Tile Source # # WTMS是最常见的平铺地图数据Web标准,即地图由标准大小的图块拼接而成,如此则可以在一个给定的缩放级别构造整个地图。WTMS使用Web Mercator格式,从英国的格林尼治向北向西测量距离,这样容易计算但不会扭曲全球形状。 # # 首先,我们创建一个覆盖美国的空白Bokeh图,范围按米计算: # In[3]: from bokeh.plotting import figure from bokeh.models.tiles import WMTSTileSource # web mercator coordinates USA = x_range,y_range = ((-13884029,-7453304), (2698291,6455972)) p = figure(tools='pan, wheel_zoom', x_range=x_range, y_range=y_range) p.axis.visible = False # `bokeh.models.tiles` 中提供了几个WTMS地图源。在这里,我们将展示通过使用格式字符串接口,Bokeh如何根据所需的缩放,X和Y值从供应商处请求图片: # In[4]: url = 'http://a.basemaps.cartocdn.com/dark_all/{Z}/{X}/{Y}.png' attribution = "Tiles by Carto, under CC BY 3.0. Data by OSM, under ODbL" p.add_tile(WMTSTileSource(url=url, attribution=attribution)) # 如果显示这个地图,那么你可以使用滚轮缩放和平移工具在任何缩放级别浏览地图,Bokeh会从服务器请求适当的图块并放在图中正确的位置: # In[5]: show(p) # 这就是在图表中放入地图数据要做的全部!当然,您通常还希望显示其他数据,除非您只想使用服务器提供的地图。现在,只要您能得到Web Mercator格式的坐标,您可以把任何您平常使用Bokeh图表想表达的东西添加到地图上。例如: # In[6]: import pandas as pd import numpy as np def wgs84_to_web_mercator(df, lon="lon", lat="lat"): """Converts decimal longitude/latitude to Web Mercator format""" k = 6378137 df["x"] = df[lon] * (k * np.pi/180.0) df["y"] = np.log(np.tan((90 + df[lat]) * np.pi/360.0)) * k return df df = pd.DataFrame(dict(name=["Austin", "NYC"], lon=[-97.7431,-74.0059], lat=[30.2672,40.7128])) wgs84_to_web_mercator(df) # In[7]: p.circle(x=df['x'], y=df['y'], fill_color='orange', size=10) show(p) # In[7]: # EXERCISE: find some data in lat, lon (e.g. at http://data.gov), # import it into a dataframe or data source, and add it on the map above. # ## GeoJSON # In[ ]: