Dmitriy Grankin
Dmitriy Grankin

Reputation: 608

How to plot Shapely polygon with Bokeh?

I want to plot shapely polygons, stored in GeoDataFrame on map with Bokeh. 1. What type of Glyph to choose to plot polygons? 2. How to pass the data to the Glyph?

I am trying to do it in the following way:

from bokeh.models import GMapOptions, PanTool, WheelZoomTool, 
    WheelPanTool, BoxSelectTool, BoxEditTool
from bokeh.plotting import gmap

p = gmap(api_key, map_options, title= f'offer {str(sales_id)} ')

map_options = GMapOptions(lat = lats_s, lng = lons_s, 
                          map_type="roadmap", zoom=12)


api_key = 'my_api_key'

x, y = some_shapely_polygon.exterior.coords.xy

x = x.tolist()
y = y.tolist()

source = ColumnDataSource(data=dict(
x=x, y=y,))

p.patches('x', 'y', source=source, 
          fill_alpha=0.8, line_color="black", line_width=0.3)
show(p)

I get an error: "Javascript Error: Invalid array length"

When I pass son other data with Circles it all works well, I I can not plot Ploygons.

Thank you!

Upvotes: 1

Views: 3012

Answers (1)

Tony
Tony

Reputation: 8297

These examples work for me. Replace map.shp with your filename. Works with Bokeh v1.0.4. Run with: python map.py

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show
import geopandas as gp
import shapely

sf = gp.read_file('map.shp')    
x, y = [], []
[(x.append(list(polygon.exterior.coords.xy[0])), y.append(list(polygon.exterior.coords.xy[1]))) for polygon in sf['geometry'] if type(polygon.boundary) == shapely.geometry.linestring.LineString ]
p = figure(title = "A map from Shapefile", plot_width = 800)
p.patches('x', 'y', source = ColumnDataSource(dict(x = x, y = y)), line_color = "white", line_width = 0.5)
show(p)

or

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show
import geopandas as gp

def getPolyCoords(row, geom, coord_type):
    if coord_type == 'x':
        return list(row[geom].exterior.coords.xy[0])
    elif coord_type == 'y':
        return list(row[geom].exterior.coords.xy[1])

gdf = gp.GeoDataFrame.from_file('map.shp')
gdf['x'] = gdf.apply(getPolyCoords, geom = 'geometry', coord_type = 'x', axis = 1)
gdf['y'] = gdf.apply(getPolyCoords, geom = 'geometry', coord_type = 'y', axis = 1)
p_df = gdf.drop('geometry', axis = 1).copy()
p = figure(title = "A map from Shapefile", plot_width = 800)
p.patches('x', 'y', source = ColumnDataSource(p_df), line_color = "white", line_width = 0.5)
show(p)

Upvotes: 2

Related Questions