How to plot points from longitudes and latitudes on a map using Bokeh and python ?


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:

How to plot points on a Bokeh map using longitude and latitude coordinates ?
How to plot points on a Bokeh map using longitude and latitude coordinates ?

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'.

How to plot points on a Bokeh map using longitude and latitude coordinates ?
How to plot points on a Bokeh map using longitude and latitude coordinates ?

References

Links Site
tile_demo docs.bokeh.org
Mapping geo data docs.bokeh.org
circle docs.bokeh.org
Image

of