Introduction
Bokeh provides a powerful framework for creating interactive data visualizations. Through the import of geographical toolkits like GeoPandas, Bokeh enables mapping points on a canvas with a simple and effective interface.
Assuming you have the necessary packages installed (Bokeh, Pandas, and Geopandas), here's a step-by-step guide to adding points defined by longitude and latitude to a map using Bokeh:
Creating a Bokeh map
To begin, let's create a map using Bokeh. There are multiple approaches and tile options available. For this example, let's use the "OpenStreetMap Mapnik" tile:
from bokeh.plotting import figure, show, output_file
p = figure(x_range=(-2000000, 6000000), y_range=(4000000, 7000000),
x_axis_type="mercator", y_axis_type="mercator")
p.add_tile("OpenStreetMap Mapnik")
p.grid.visible = False
show(p)
The plot above will generate the following visualization:
In order to accurately plot points on a map, it is crucial to determine the projection system used. In this case, our map employs the Mercator projection. To plot our points correctly, we need to convert the longitudes and latitudes to the appropriate coordinate system. A highly effective tool for accomplishing this in Python is a geopandas dataframe. In the following example, we will demonstrate how to store your data in a geopandas dataframe and convert the coordinate system to ultimately plot our points.
Creating a collection of coordinates using latitude and longitude values
For instance, we can generate a dataset that includes coordinates (latitude and longitude) for different cities:
data = {'city_name':['Paris','London','Moscow', 'Istanbul'],
'longitude':[2.3522,-0.1276,37.6173,28.9784],
'latitude':[48.8566,51.5072,55.7558,41.0082]}
Creating a geopandas dataframe
Let us proceed to store our data in a pandas dataframe:
import pandas as pd
df = pd.DataFrame(data)
and convert our Dataframe into a Geodataframe
import geopandas
gdf = geopandas.GeoDataFrame(
df,
geometry=geopandas.points_from_xy(df.longitude, df.latitude),
crs="EPSG:4326"
)
To determine the coordinate system CRS associated with our dataframe, we can execute the following command:
print( gdf.crs )
The code presented here does not correspond to Mercantor:
EPSG:4326
In order to convert our geopandas into the Mercator-projection we can do:
gdf = gdf.to_crs("epsg:3857") # Mercator-projection
At last, our dataset has transformed into the following format:
city_name longitude latitude geometry
0 Paris 2.3522 48.8566 POINT (261845.706 6250564.350)
1 London -0.1276 51.5072 POINT (-14204.367 6711506.705)
2 Moscow 37.6173 55.7558 POINT (4187538.681 7509955.142)
3 Istanbul 28.9784 41.0082 POINT (3225860.732 5013551.237)
In the final step, we will extract the coordinates in the Mercator projection that correspond to the given longitudes and latitudes
gdf['longitude_x'] = gdf['geometry'].x
gdf['latitude_y'] = gdf['geometry'].y
Now, the geodataframe has two new columns that will be used to plot our points:
city_name longitude latitude geometry \
0 Paris 2.3522 48.8566 POINT (261845.706 6250564.350)
1 London -0.1276 51.5072 POINT (-14204.367 6711506.705)
2 Moscow 37.6173 55.7558 POINT (4187538.681 7509955.142)
3 Istanbul 28.9784 41.0082 POINT (3225860.732 5013551.237)
longitude_x latitude_y
0 2.618457e+05 6.250564e+06
1 -1.420437e+04 6.711507e+06
2 4.187539e+06 7.509955e+06
3 3.225861e+06 5.013551e+06
Creating a bokeh ColumnDataSource
We can now store our data in a Bokeh ColumnDataSource. To achieve this, we can utilize a pandas dataframe. As a result, we need to convert our geopandas dataframe mentioned earlier and remove the column "geometry" as Bokeh does not recognize this column.
df_new = pd.DataFrame(gdf.drop(columns='geometry'))
Now we can create a bokeh ColumnDataSource:
from bokeh.models import ColumnDataSource
source = ColumnDataSource(df_new)
Plotting points on a Bokeh map
We can now visualize our data on the map by plotting the points using the p.circle() function:
from bokeh.plotting import figure, show, output_file
p = figure(x_range=(-2000000, 6000000), y_range=(4000000, 7000000),
x_axis_type="mercator", y_axis_type="mercator")
p.add_tile("OpenStreetMap Mapnik")
p.circle(x='longitude_x', y='latitude_y', size=15, alpha=0.7, source=source)
p.grid.visible = False
show(p)
This will create circles with a size of 15, an alpha value of 0.7, and the data source specified as 'source'.
References
Links | Site |
---|---|
tile_demo | docs.bokeh.org |
Mapping geo data | docs.bokeh.org |
circle | docs.bokeh.org |