☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

H3 hexagon overlaid on maps with Bokeh

Community Supportbokeh
arashm
arashm

Hi,

I’ve searched for a working example of overlaying a map with h3 hexagons using Bokeh. There are a lot of examples using other rendering libraries like Folium but not with Bokeh. If anyone has done this before and can share an example, I’d appreciate it.

Thanks
Arash

⌁   Link to post
arashm
arashm

H3 is Uber’s Hexagonal Hierarchical Geospatial Indexing System in Python:

https://uber.github.io/h3-py/intro.html

For example, the hexagonal in which the following point belongs to is:

import h3

lat, lng = 37.769377, -122.388903
h3_resolution = 9
h3index = h3.geo_to_h3(lat, lng, h3_resolution)
polygon = h3.h3_to_geo_boundary(h3index

The polygon is a list of 6 pairs of long/lats. I want to decorate (overlay) several of these hexagons on a map.

⌁   Link to post
arashm
arashm

Thanks for the tip. This is what I came up. It runs a bit slow for large dataframes so if anyone knows how to speed it up, please let me know.

import h3
import h3pandas
import pandas as pd
import geopandas as gpd
from bokeh.plotting import figure, show
from bokeh.tile_providers import get_provider
import xyzservices.providers as xyz

lat, lng = 32.733801, -117.193394
h3_resolution = 9
h3index = h3.geo_to_h3(lat, lng, h3_resolution)
h3index = list(h3.k_ring(h3index, 1))

df = pd.DataFrame(index=h3index)
df = df.h3.h3_to_geo_boundary()
df.reset_index(inplace=True)
df.rename(columns={'geometry': 'Polygon'}, inplace=True)
df['Polygon'].set_crs(crs='epsg:4324', allow_override=True, inplace=True)

def extract_xy(df):
    xx, yy = df['geometry'].exterior.coords.xy
    df['xx'] = xx.tolist()
    df['yy'] = yy.tolist()
    return df

df['geometry'] = df['Polygon'].to_crs('epsg:3857')
# line below is quite slow when dataframe size is large
df = df.apply(extract_xy, axis=1)

x_min = min(min(df['xx'].tolist(), key=min))
x_max = max(max(df['xx'].tolist(), key=max))
y_min = min(min(df['yy'].tolist(), key=min))
y_max = max(max(df['yy'].tolist(), key=max))

tile_provider = get_provider(xyz.OpenStreetMap.Mapnik)

TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select,hover"
p = figure(width=800, height=800, 
           x_range = (x_min,x_max), y_range=(y_min,y_max),
                   x_axis_type="mercator", y_axis_type="mercator", 
                   tools = TOOLS)

p.add_tile(tile_provider)
p.patches(df['xx'].tolist(), df['yy'].tolist(), color=["firebrick"]*df.shape[0], alpha=[0.2]*df.shape[0], line_width=2)

show(p)

⌁   Link to post

End of archived discussion · Replies are disabled