Data used: Boundary-Line™ (https://osdatahub.os.uk/downloads/open/BoundaryLine)
# import libraries
import geopandas as gpd
from bokeh.io import output_notebook
from bokeh.models import (
CategoricalColorMapper, LogColorMapper, GeoJSONDataSource
)
from bokeh.palettes import viridis
from bokeh.plotting import figure, show
from bokeh.tile_providers import CARTODBPOSITRON_RETINA, get_provider
# specify map tile provider
tile_provider = get_provider(CARTODBPOSITRON_RETINA)
# import data
data = gpd.read_file(
"data/os_bdline/data/bdline_gb.gpkg", layer="greater_london_const"
)
data["Name"] = data["Name"].str.slice(stop=-18)
# view data
data.head(5)
Name | Area_Code | Area_Description | File_Name | Feature_Serial_Number | Collection_Serial_Number | Global_Polygon_ID | Admin_Unit_ID | Census_Code | Hectares | Non_Inland_Area | Area_Type_Code | Area_Type_Description | Non_Area_Type_Code | Non_Area_Type_Description | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Havering and Redbridge | LAC | Greater London Authority Assembly Constituency | GREATER_LONDON_AUTHORITY | 1 | 1 | 112074 | 41452 | E32000009 | 17089.120 | 215.025 | VA | CIVIL VOTING AREA | None | None | MULTIPOLYGON (((552057.328 178434.366, 552047.... |
1 | Croydon and Sutton | LAC | Greater London Authority Assembly Constituency | GREATER_LONDON_AUTHORITY | 2 | 2 | 112056 | 41443 | E32000005 | 13033.641 | 0.000 | VA | CIVIL VOTING AREA | None | None | MULTIPOLYGON (((531409.308 171042.621, 531439.... |
2 | Bexley and Bromley | LAC | Greater London Authority Assembly Constituency | GREATER_LONDON_AUTHORITY | 3 | 3 | 112066 | 41448 | E32000002 | 21444.820 | 373.731 | VA | CIVIL VOTING AREA | None | None | MULTIPOLYGON (((549944.025 181074.392, 549992.... |
3 | South West | LAC | Greater London Authority Assembly Constituency | GREATER_LONDON_AUTHORITY | 4 | 4 | 112076 | 41453 | E32000013 | 15259.573 | 198.064 | VA | CIVIL VOTING AREA | None | None | MULTIPOLYGON (((519458.306 179569.530, 519465.... |
4 | Ealing and Hillingdon | LAC | Greater London Authority Assembly Constituency | GREATER_LONDON_AUTHORITY | 5 | 5 | 112054 | 41442 | E32000006 | 17124.643 | 0.000 | VA | CIVIL VOTING AREA | None | None | MULTIPOLYGON (((504288.900 193543.098, 504292.... |
# reproject to web mercator
data = data.to_crs(3857)
# convert data source to GeoJSON
geo_source = GeoJSONDataSource(geojson=data.to_json())
# generate unique colours for each constituency
const = list(set(data["Name"]))
palette = viridis(len(const))
color_map = CategoricalColorMapper(factors=const, palette=palette)
# define plot title
TITLE = (
"Greater London Constituencies. Contains OS Data" +
" © Crown copyright and database right 2021."
)
# configure plot
p = figure(
title=TITLE,
tools="wheel_zoom, pan, reset, hover, save",
x_axis_location=None,
y_axis_location=None,
tooltips=[("Name", "@Name"), ("Hectares", "@Hectares")],
x_axis_type="mercator",
y_axis_type="mercator"
)
p.grid.grid_line_color = None
p.hover.point_policy = "follow_mouse"
p.patches(
"xs",
"ys",
source=geo_source,
fill_color={"field": "Name", "transform": color_map},
line_color="white",
line_width=.5,
fill_alpha=.7
)
p.add_tile(tile_provider)
# display plot
show(p)