Share @ LinkedIn Facebook  bokeh, maps
Plotting Maps using Bokeh

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

Bokeh has been the go-to library for many python data scientists for visualization purposes. Bokeh provides good support for handling and visualizing geospatial data. We have already covered the basics of bokeh in other tutorials and will be covering about plotting interactive maps using bokeh in this tutorial. Bokeh provides an easy interface to access various map tiles from tile providers which provide different types of maps which can be used as a base plot on which other scatter plot, connection lines can be plotted. We'll be primarily plotting three different maps using bokeh in this tutorial.

  • Scatter Maps
  • Connection Maps
  • Choropleth Maps

We'll be using different datasets and aggregate their data in various ways to plot different types of map charts mentioned above. We'll start by loading important libraries.

In [ ]:
import pandas as pd
import numpy as np

from bokeh.plotting import figure
from bokeh.tile_providers import get_provider, WIKIMEDIA, CARTODBPOSITRON, STAMEN_TERRAIN, STAMEN_TONER, ESRI_IMAGERY, OSM
from bokeh.io import output_notebook, show

import warnings

warnings.filterwarnings("ignore")
pd.set_option("max_columns", 30)

output_notebook()

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

We suggest that you download the datasets and follow along with us using the same datasets to better understand the material and get an in-depth idea about the whole process. We'll first load the datasets as pandas dataframe and aggregate it in various ways to create different chord diagrams.

NOTE

Please make a note that original brazil flights dataset is quite big with size of 600+ MB and nearly 2.5 Mn rows. If you have low RAM then you can use nrows attribute of read_csv() method to load only first few thousand entries to follow along with tutorial without getting stuck. We have loaded only 100k entries for making things simple for explanation purpose.

In [2]:
starbucks = pd.read_csv("datasets/starbucks_store_locations.csv")
starbucks.head()
Out[2]:
Brand Store Number Store Name Ownership Type Street Address City State/Province Country Postcode Phone Number Timezone Longitude Latitude
0 Starbucks 47370-257954 Meritxell, 96 Licensed Av. Meritxell, 96 Andorra la Vella 7 AD AD500 376818720 GMT+1:00 Europe/Andorra 1.53 42.51
1 Starbucks 22331-212325 Ajman Drive Thru Licensed 1 Street 69, Al Jarf Ajman AJ AE NaN NaN GMT+04:00 Asia/Dubai 55.47 25.42
2 Starbucks 47089-256771 Dana Mall Licensed Sheikh Khalifa Bin Zayed St. Ajman AJ AE NaN NaN GMT+04:00 Asia/Dubai 55.47 25.39
3 Starbucks 22126-218024 Twofour 54 Licensed Al Salam Street Abu Dhabi AZ AE NaN NaN GMT+04:00 Asia/Dubai 54.38 24.48
4 Starbucks 17127-178586 Al Ain Tower Licensed Khaldiya Area, Abu Dhabi Island Abu Dhabi AZ AE NaN NaN GMT+04:00 Asia/Dubai 54.54 24.51
In [3]:
brazil_flights = pd.read_csv("brazil_flights_data.csv", nrows=100000, encoding="latin")
brazil_flights = brazil_flights.rename(columns={"Cidade.Origem":"City_Orig", "Cidade.Destino":"City_Dest",
                               "Estado.Origem":"State_Orig", "Estado.Destino":"State_Dest",
                               "Pais.Origem":"Country_Orig", "Pais.Destino":"Country_Dest",
                               "Aeroporto.Origem":"Airport_Orig", "Aeroporto.Destino":"Airport_Dest"})

brazil_flights.head()
Out[3]:
Voos Companhia.Aerea Codigo.Tipo.Linha Partida.Prevista Partida.Real Chegada.Prevista Chegada.Real Situacao.Voo Codigo.Justificativa Airport_Orig City_Orig State_Orig Country_Orig Airport_Dest City_Dest State_Dest Country_Dest LongDest LatDest LongOrig LatOrig
0 AAL - 203 AMERICAN AIRLINES INC Internacional 2016-01-30T08:58:00Z 2016-01-30T08:58:00Z 2016-01-30T10:35:00Z 2016-01-30T10:35:00Z Realizado NaN Afonso Pena Sao Jose Dos Pinhais PR Brasil Salgado Filho Porto Alegre RS Brasil -51.175381 -29.993473 -49.172481 -25.532713
1 AAL - 203 AMERICAN AIRLINES INC Internacional 2016-01-13T12:13:00Z 2016-01-13T12:13:00Z 2016-01-13T21:30:00Z 2016-01-13T21:30:00Z Realizado NaN Salgado Filho Porto Alegre RS Brasil Miami Miami N/I Estados Unidos -80.287046 25.795865 -51.175381 -29.993473
2 AAL - 203 AMERICAN AIRLINES INC Internacional 2016-01-29T12:13:00Z 2016-01-29T12:13:00Z 2016-01-29T21:30:00Z 2016-01-29T21:30:00Z Realizado NaN Salgado Filho Porto Alegre RS Brasil Miami Miami N/I Estados Unidos -80.287046 25.795865 -51.175381 -29.993473
3 AAL - 203 AMERICAN AIRLINES INC Internacional 2016-01-19T12:13:00Z 2016-01-18T12:03:00Z 2016-01-19T21:30:00Z 2016-01-18T20:41:00Z Realizado LIBERACAO SERV. TRAFEGO AEREO/ANTECIPACAO Salgado Filho Porto Alegre RS Brasil Miami Miami N/I Estados Unidos -80.287046 25.795865 -51.175381 -29.993473
4 AAL - 203 AMERICAN AIRLINES INC Internacional 2016-01-30T12:13:00Z 2016-01-30T12:13:00Z 2016-01-30T21:30:00Z 2016-01-30T21:30:00Z Realizado NaN Salgado Filho Porto Alegre RS Brasil Miami Miami N/I Estados Unidos -80.287046 25.795865 -51.175381 -29.993473
In [4]:
us_state_population = pd.read_csv("datasets/State Populations.csv")
us_state_population.columns = ["State", "Population"]
us_state_population.head()
Out[4]:
State Population
0 California 39776830
1 Texas 28704330
2 Florida 21312211
3 New York 19862512
4 Pennsylvania 12823989

The process of plotting a map using a bokeh consists of a few steps.

  • We need to load tile from the list of tile providers available from bokeh.tile_providers.
  • We need to create a figure with x and y-axis type as Mercator in order to load the chart as a geo chart.
  • We need to add loaded tile to figure.
  • We can then call other bokeh charting methods like a circle(), square(), line(), etc to plot other charts (glyphs) above maps.
NOTE

Please make a note that bokeh only accepts web Mercator projection data hence we need to convert all our latitude and longitude projection data to web Mercator system. We'll be using pyproj library in order to map data from latitude/longitude projection to we Mercator projection.

Sample Map

Below we have created the first simple map which highlights a particular area of the world using WIKIMEDIA projection. It’s a tile provided by Wikipedia. We have simply followed the above steps without adding new glyphs on the chart. Please make a note that we have provided x and y range of charts as web Mercator projection data.

In [ ]:
wikimedia = get_provider(WIKIMEDIA)

fig = figure(plot_width=800, plot_height=700,
           x_range=(6000000, 8000000), y_range=(-1000000, 7000000),
           x_axis_type="mercator", y_axis_type="mercator")

fig.add_tile(wikimedia)


show(fig)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

World Map

Below we have plotted the world map using the CARTODBPOSITRON tile. We have first found of web Mercator projection for a world based on latitudes and longitudes of the world. We are then using that web Mercator projected data to set a range of x and y-axis.

In [6]:
from pyproj import Proj, transform

inProj = Proj(init='epsg:3857')
outProj = Proj(init='epsg:4326')

world_lon1, world_lat1 = transform(outProj,inProj,-180,-85)
world_lon2, world_lat2 = transform(outProj,inProj,180,85)
In [ ]:
cartodb = get_provider(CARTODBPOSITRON)

fig = figure(plot_width=800, plot_height=700,
             x_range=(world_lon1, world_lon2),
             y_range=(world_lat1, world_lat2),
             x_axis_type="mercator", y_axis_type="mercator")

fig.add_tile(cartodb)

show(fig)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

Starbucks US Store Locations Scatter Map

Below we are creating our first scatter map using bokeh. We are the first filtering rows of Starbucks locations and keeping only rows where the country is the US. We are then converting store locations data present in latitude and longitude to web Mercator projection data. We are setting that mapped data into the pandas dataframe. We have then used that data for plotting circles on top of the US Map. We have used WIKIMEDIA projection this time.

We also have used tooltip which highlights latitude, longitude, state, and name of the store when someone hovers over any point in the scatter map.

In [8]:
%%time

starbucks_us = starbucks[starbucks.Country == "US"]

lons, lats = [], []
for lon, lat in list(zip(starbucks_us["Longitude"], starbucks_us["Latitude"])):
    x, y = transform(outProj,inProj,lon,lat)
    lons.append(x)
    lats.append(y)
CPU times: user 7min 9s, sys: 8.82 s, total: 7min 18s
Wall time: 7min 18s
In [9]:
starbucks_us["MercatorX"] = lons
starbucks_us["MercatorY"] = lats

starbucks_us = starbucks_us.rename(columns={"Store Name":"Name", "State/Province":"State"})
starbucks_us.head()
Out[9]:
Brand Store Number Name Ownership Type Street Address City State Country Postcode Phone Number Timezone Longitude Latitude MercatorX MercatorY
11964 Starbucks 3513-125945 Safeway-Anchorage #1809 Licensed 5600 Debarr Rd Ste 9 Anchorage AK US 995042300 907-339-0900 GMT-09:00 America/Anchorage -149.78 61.21 -1.667343e+07 8.674203e+06
11965 Starbucks 74352-84449 Safeway-Anchorage #2628 Licensed 1725 Abbott Rd Anchorage AK US 995073444 907-339-2800 GMT-09:00 America/Anchorage -149.84 61.14 -1.668011e+07 8.658040e+06
11966 Starbucks 12449-152385 Safeway - Anchorage #1813 Licensed 1501 Huffman Rd Anchorage AK US 995153596 907-339-1300 GMT-09:00 America/Anchorage -149.85 61.11 -1.668123e+07 8.651125e+06
11967 Starbucks 24936-233524 100th & C St - Anchorage Company Owned 320 W. 100th Ave, 100, Southgate Shopping Ctr ... Anchorage AK US 99515 (907) 227-9631 GMT-09:00 America/Anchorage -149.89 61.13 -1.668568e+07 8.655734e+06
11968 Starbucks 8973-85630 Old Seward & Diamond Company Owned 1005 E Dimond Blvd Anchorage AK US 995152050 907-344-4160 GMT-09:00 America/Anchorage -149.86 61.14 -1.668234e+07 8.658040e+06
In [ ]:
wikimedia = get_provider(WIKIMEDIA)

us_lon1, us_lat1 = transform(outProj,inProj,-140,10)
us_lon2, us_lat2 = transform(outProj,inProj,-50,55)

p = figure(plot_width=900, plot_height=700,
           x_range=(us_lon1, us_lon2), y_range=(us_lat1, us_lat2),
           x_axis_type="mercator", y_axis_type="mercator",
           tooltips=[
                    ("State", "@State"), ("Name", "@Name"), ("(Long, Lat)", "(@Longitude, @Latitude)")
                    ],
           title="Starbucks Store Locations US")

p.add_tile(wikimedia)

p.circle(x="MercatorX", y="MercatorY",
         size=2,
         fill_color="dodgerblue", line_color="dodgerblue",
         fill_alpha=0.3,
         source=starbucks_us)

show(p)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

Starbucks Stores Count Per State Scatter Map

We are now creating another scatter map which highlights Starbucks store count per various state of the world. We are the first aggregating data of Starbucks location by grouping it according to the state of each country and getting count per state. We are then taking an average of latitude and longitude of stores per state in order to get latitude and longitude of state. We are then converting latitude and longitude data to web Mercator projection data and adding it to the dataframe.

We have then used the final dataframe to plot a scatter chart on world maps. We have also used tooltip which highlights state name, store count per state, latitude, and longitude of state information when someone hovers over any point in the chart.

In [11]:
starbucks_cnt_per_state = starbucks.groupby(by="State/Province").count()[["Store Number"]]\
                            .rename(columns={"Store Number":"Count"})
starbucks_avg_lat_lon = starbucks.groupby(by="State/Province").mean()[["Longitude", "Latitude"]]

starbucks_cnt_per_state = starbucks_cnt_per_state.join(starbucks_avg_lat_lon)
starbucks_cnt_per_state = starbucks_cnt_per_state.reset_index().rename(columns={"State/Province":"State"})
starbucks_cnt_per_state.head()
Out[11]:
State Count Longitude Latitude
0 0 89 121.035618 14.572697
1 1 193 90.336788 17.152539
2 10 275 101.766000 12.460582
3 11 706 121.629702 37.964255
4 12 145 123.439448 33.032483
In [12]:
lons, lats = [], []
for lon, lat in list(zip(starbucks_cnt_per_state["Longitude"], starbucks_cnt_per_state["Latitude"])):
    x, y = transform(outProj,inProj,lon,lat)
    lons.append(x)
    lats.append(y)
In [13]:
starbucks_cnt_per_state["MercatorX"] = lons
starbucks_cnt_per_state["MercatorY"] = lats
In [ ]:
p = figure(plot_width=800, plot_height=600,
           x_range=(world_lon1, world_lon2), y_range=(world_lat1, world_lat2),
           x_axis_type="mercator", y_axis_type="mercator",
           tooltips=[
                    ("State", "@State"), ("Count", "@Count"), ("(Long, Lat)", "(@Longitude, @Latitude)")
                    ],
           title="Starbucks Store Count Per State")

p.add_tile(cartodb)

p.circle(x="MercatorX", y="MercatorY",
         size=4,
         fill_color="tomato", line_color="tomato",
         fill_alpha=0.3,
         source=starbucks_cnt_per_state,
         )

show(p)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

Flights From Brazil To Other Countries Connection Map

The second type of chart that we'll be plotting using bokeh is a connection map. We'll follow the same steps as mentioned earlier but will use the Brazil flight dataset this time for explanation purposes.

The connection map that we'll plot using the Brazil flights dataset will show flights from brazil to all other countries along with their count when hovered over the endpoint of the edge. We'll first filter the brazil flight dataset to keep only rows where the source country is brazil. We'll then aggregate data to keep all combinations of flights from Brazil to other countries to get a count of flights from brazil to all other countries. We'll then convert source and destination latitude/longitude data to web Mercator projection and add it to the dataframe for later use.

We have used STAMEN_TONER and ESRI_IMAGERY tiles for this chart. We have used line and circle glyphs of bokeh to plot a line between the source and destination of flight and highlight source and destinations. We have also used tooltip which highlights the source country, the destination country, and a number of flights to that country.

In [15]:
flights_from_brazil = brazil_flights[brazil_flights.Country_Orig == 'Brasil']
flights_from_brazil_cnt = flights_from_brazil.groupby(by=["Country_Orig", "Country_Dest"]).count()[["Voos"]].rename(columns={"Voos":"Count"})
flights_from_brazil_lat_lon = flights_from_brazil.groupby(by=["Country_Orig", "Country_Dest"]).mean()[["LongDest","LatDest","LongOrig","LatOrig"]]
flights_from_brazil_cnt = flights_from_brazil_cnt.join(flights_from_brazil_lat_lon).reset_index()

flights_from_brazil_cnt.head()
Out[15]:
Country_Orig Country_Dest Count LongDest LatDest LongOrig LatOrig
0 Brasil Africa Do Sul 45 28.241146 -26.136673 -46.478126 -23.434553
1 Brasil Alemanha 147 9.239697 49.682746 -44.737826 -21.822414
2 Brasil Angola 31 13.234862 -8.847951 -45.124154 -23.174074
3 Brasil Antilhas Holandesas 31 -69.571231 12.370281 -56.107170 -8.958052
4 Brasil Argentina 1796 -58.827371 -34.644030 -45.827534 -23.188851
In [16]:
cols = ["LongDest","LatDest","LongOrig","LatOrig"]

lines_x, lines_y = [],[]
lons, lats = [], []

for lon_dest, lat_dest, lon_orig, lat_orig in flights_from_brazil_cnt[cols].values:
    lon_orig, lat_orig = transform(outProj,inProj,lon_orig,lat_orig)
    lon_dest, lat_dest = transform(outProj,inProj,lon_dest,lat_dest)

    lons.append(lon_dest)
    lats.append(lat_dest)

    lines_x.append([lon_orig, lon_dest])
    lines_y.append([lat_orig, lat_dest])

flights_from_brazil_cnt["MercatorX"] = lons
flights_from_brazil_cnt["MercatorY"] = lats
flights_from_brazil_cnt.head()
Out[16]:
Country_Orig Country_Dest Count LongDest LatDest LongOrig LatOrig MercatorX MercatorY
0 Brasil Africa Do Sul 45 28.241146 -26.136673 -46.478126 -23.434553 3.143790e+06 -3.016018e+06
1 Brasil Alemanha 147 9.239697 49.682746 -44.737826 -21.822414 1.028558e+06 6.391513e+06
2 Brasil Angola 31 13.234862 -8.847951 -45.124154 -23.174074 1.473298e+06 -9.888876e+05
3 Brasil Antilhas Holandesas 31 -69.571231 12.370281 -56.107170 -8.958052 -7.744634e+06 1.387878e+06
4 Brasil Argentina 1796 -58.827371 -34.644030 -45.827534 -23.188851 -6.548633e+06 -4.115611e+06
In [ ]:
stamen_toner = get_provider(STAMEN_TONER)

world_lon1, world_lat1 = transform(outProj,inProj,-150,-75)
world_lon2, world_lat2 = transform(outProj,inProj,140,75)

p = figure(plot_width=800, plot_height=700,
           x_range=(world_lon1, world_lon2), y_range=(world_lat1, world_lat2),
           x_axis_type="mercator", y_axis_type="mercator",
           tooltips=[
                    ("Source", "@Country_Orig"), ("Destination", "@Country_Dest"), ("Count", "@Count")
                    ],
           title="Starbucks Store Count Per State")

p.add_tile(stamen_toner)

p.multi_line(lines_x, lines_y, color="red")

p.circle(x="MercatorX", y="MercatorY",
         size=10, alpha=0.8, color="lime",
         source=flights_from_brazil_cnt)


show(p)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

In [ ]:
esri = get_provider(ESRI_IMAGERY)

world_lon1, world_lat1 = transform(outProj,inProj,-150,-75)
world_lon2, world_lat2 = transform(outProj,inProj,140,75)

p = figure(plot_width=800, plot_height=700,
           x_range=(world_lon1, world_lon2), y_range=(world_lat1, world_lat2),
           x_axis_type="mercator", y_axis_type="mercator",
           tooltips=[
                    ("Source", "@Country_Orig"), ("Destination", "@Country_Dest"), ("Count", "@Count")
                    ],
           title="Starbucks Store Count Per State")

p.add_tile(esri)

p.multi_line(lines_x, lines_y, color="lime")

p.circle(x="MercatorX", y="MercatorY",
         size=10, alpha=0.9, color="tomato",
         source=flights_from_brazil_cnt)


show(p)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

United States Starbucks Store Count Per State Choropleth Map

The third chart type that we'll introduce using bokeh is a choropleth map. The process of plotting choropleth maps using bokeh is different from previous chart types. It does not need any tile providers or latitude/longitude information.

The first choropleth map that we'll plot using bokeh is Starbucks store count per US states. It'll color code states of the US according to the count of Starbucks stores in that state.

We'll be first loading US states boundary data which is available in bokeh as a part of bokeh.sampledata.us_states. We'll load it as a pandas dataframe so that we have each state’s boundary latitude and longitude data. We'll be using this list of latitude and longitudes to create a polygon consisting of the US state by using the patches() glyph of bokeh. We have also merged Starbucks store counts per state data with this boundary data so that we have all data available in a single dataframe.

We have then created single dictionary consisting of this data which will be used as a source of a choropleth map. We have used bokeh LogColorMapper which maps the count of store per state to a particular color in the selected color palette.

In [19]:
from bokeh.models import LogColorMapper
from bokeh.palettes import Oranges256 as oranges
from bokeh.sampledata.us_states import data as us_states
In [20]:
us_states_df = pd.DataFrame(us_states).T
us_states_df = us_states_df[~us_states_df["name"].isin(['Alaska', "Hawaii"])]
us_states_df["lons"] = us_states_df.lons.values.tolist()
us_states_df["lats"] = us_states_df.lats.values.tolist()
us_states_df = us_states_df.reset_index()
us_states_df = us_states_df.merge(starbucks_cnt_per_state[["State", "Count"]], how="left", left_on="index", right_on="State")

us_states_df.head()
Out[20]:
index name region lats lons State Count
0 NV Nevada Southwest [40.68928, 40.4958, 40.30302, 40.09896, 39.999... [-114.04392, -114.04558, -114.04619, -114.0464... NV 253
1 AZ Arizona Southwest [34.87057, 35.00186, 35.00332, 35.07971, 35.11... [-114.63332, -114.63349, -114.63423, -114.6089... AZ 536
2 WI Wisconsin Central [42.49273, 42.49433, 42.49562, 42.49561, 42.49... [-87.8156, -87.93137, -88.10268, -88.20645, -8... WI 145
3 GA Georgia Southeast [32.29667, 32.24425, 32.09197, 32.03256, 32.02... [-81.12387, -81.15654, -81.02071, -80.75203, -... GA 326
4 KS Kansas Central [36.99927, 36.99879, 36.99914, 36.99903, 36.99... [-96.28415, -96.55381, -96.91244, -97.1197, -9... KS 94
In [21]:
us_states_datasource = {}
us_states_datasource["lons"] = us_states_df.lons.values.tolist()
us_states_datasource["lats"] = us_states_df.lats.values.tolist()
us_states_datasource["name"] = us_states_df.name.values.tolist()
us_states_datasource["StateCodes"] = us_states_df.index.values.tolist()
us_states_datasource["StarbuckStores"] = us_states_df.Count.values.tolist()
In [ ]:
fig = figure(plot_width=900, plot_height=600,
             title="United States Starbucks Store Count Per State Choropleth Map",
             x_axis_location=None, y_axis_location=None,
             tooltips=[
                        ("Name", "@name"), ("StarbuckStores", "@StarbuckStores"), ("(Long, Lat)", "($x, $y)")
                      ])

fig.grid.grid_line_color = None

fig.patches("lons", "lats", source=us_states_datasource,
            fill_color={'field': 'StarbuckStores', 'transform': LogColorMapper(palette=oranges[::-1])},
            fill_alpha=0.7, line_color="white", line_width=0.5)

show(fig)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

The United States Population Per State [2018] Choropleth Map

The second choropleth map that we have created using bokeh is the US state population choropleth map. We have merged the US state population dataframe loaded at the beginning with the dataframe of the previous step and also added population count to the data source dictionary created in the previous step. We have used the same data source dictionary which we have used in the previous step with this data added to plot choropleth map.

In [23]:
us_states_df = us_states_df.merge(us_state_population, how="left", left_on="name", right_on="State")

us_states_df.head()
Out[23]:
index name region lats lons State_x Count State_y Population
0 NV Nevada Southwest [40.68928, 40.4958, 40.30302, 40.09896, 39.999... [-114.04392, -114.04558, -114.04619, -114.0464... NV 253 Nevada 3056824
1 AZ Arizona Southwest [34.87057, 35.00186, 35.00332, 35.07971, 35.11... [-114.63332, -114.63349, -114.63423, -114.6089... AZ 536 Arizona 7123898
2 WI Wisconsin Central [42.49273, 42.49433, 42.49562, 42.49561, 42.49... [-87.8156, -87.93137, -88.10268, -88.20645, -8... WI 145 Wisconsin 5818049
3 GA Georgia Southeast [32.29667, 32.24425, 32.09197, 32.03256, 32.02... [-81.12387, -81.15654, -81.02071, -80.75203, -... GA 326 Georgia 10545138
4 KS Kansas Central [36.99927, 36.99879, 36.99914, 36.99903, 36.99... [-96.28415, -96.55381, -96.91244, -97.1197, -9... KS 94 Kansas 2918515
In [24]:
us_states_datasource["Population"] = us_states_df.Population.values.tolist()
In [ ]:
from bokeh.palettes import YlGnBu9 as YlGnBu

fig = figure(plot_width=900, plot_height=600,
             title="United States Population Per State [2018] Choropleth Map",
             x_axis_location=None, y_axis_location=None,
             tooltips=[
                        ("Name", "@name"), ("Population", "@Population"), ("(Long, Lat)", "($x, $y)")
                      ])

fig.grid.grid_line_color = None

fig.patches("lons", "lats", source=us_states_datasource,
            fill_color={'field': 'Population', 'transform': LogColorMapper(palette=YlGnBu[::-1])},
            fill_alpha=0.7, line_color="white", line_width=0.5)

show(fig)

Plotting Maps using Bokeh [Scatter Maps, Connection Maps & Choropleth Maps]

This ends our small tutorial on creating a scatter map, connection map, and choropleth map using bokeh. Please feel free to let us know your views in the comments section.



Sunny Solanki  Sunny Solanki