Plotly maps#
Various map types and overlays are available.
Open Street Map is open for use without a token.
Overlays include scatter, lines, densities, etc.
Choropleths (coloured map sections) can be used as overlays or as separate plots when a GeoJSON formated dictionary of map polygons are available.
# The following renders plotly graphs in Jupyter Notebook, Jupyter Lab and VS Code formats
import plotly.io as pio
pio.renderers.default = "notebook+plotly_mimetype"
Map#
Various maps with user defined overlays are available, e.g., scatter_map.
From Plotly version 5.24, Mapbox-es are deprecated, e.g., scatter_mapbox.
Writer has, as of 16. November 2024, not made the switch yet.
In most cases, switching between map and mapbox does not require other code changes.
import plotly.express as px
import pandas as pd
us_cities = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv"
)
fig = px.scatter_mapbox(
us_cities,
lat="lat",
lon="lon",
hover_name="City",
hover_data=["State", "Population"],
color_discrete_sequence=["fuchsia"],
zoom=3,
height=300,
width=600,
)
fig.update_layout(mapbox_style="open-street-map")
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
fig.update_layout(mapbox_bounds={"west": -180, "east": -50, "south": 20, "north": 90})
fig
A local example from Ås#
import pandas as pd
# Local restaurants and cafes
restaurants = pd.read_csv('../../data/restaurants.csv')
restaurants
name | lat | lon | type | |
---|---|---|---|---|
0 | Sushiko Ås | 59.664773 | 10.789674 | Restaurant |
1 | Charlie's Diner | 59.664663 | 10.788735 | Restaurant |
2 | Jojo's Pizza | 59.665496 | 10.795366 | Restaurant |
3 | Desi Zaiqa | 59.664281 | 10.792276 | Restaurant |
4 | Babylon Pizza | 59.663602 | 10.792977 | Restaurant |
5 | NT kiosk | 59.663743 | 10.793237 | Kiosk |
6 | Aas Bistro | 59.663465 | 10.793558 | Restaurant |
7 | Whytes Coffee | 59.664686 | 10.790830 | Café |
8 | Station kiosk Ås | 59.663324 | 10.794335 | Café |
fig_restaurants = px.scatter_mapbox(
restaurants,
lat="lat",
lon="lon",
hover_name="name",
hover_data=["type","lat","lon"],
color_discrete_sequence=["fuchsia"],
zoom=14,
height=600,
width=700,
)
fig_restaurants.update_layout(mapbox_style="open-street-map")
fig_restaurants.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
#fig_restaurants.update_traces(cluster=dict(enabled=True)) # Group restaurants when zooming out
fig_restaurants
print(fig_restaurants)
Figure({
'data': [{'customdata': array([['Restaurant', 59.6647728, 10.7896737],
['Restaurant', 59.6646628, 10.7887347],
['Restaurant', 59.6654962, 10.7953659],
['Restaurant', 59.6642813, 10.7922755],
['Restaurant', 59.6636019, 10.7929767],
['Kiosk', 59.6637434, 10.7932373],
['Restaurant', 59.663465, 10.7935577],
['Café', 59.6646862, 10.7908304],
['Café', 59.663324, 10.7943351]], dtype=object),
'hovertemplate': ('<b>%{hovertext}</b><br><br>lat' ... '{customdata[0]}<extra></extra>'),
'hovertext': array(['Sushiko Ås', "Charlie's Diner", "Jojo's Pizza", 'Desi Zaiqa',
'Babylon Pizza', 'NT kiosk', 'Aas Bistro', 'Whytes Coffee',
'Station kiosk Ås'], dtype=object),
'lat': array([59.6647728, 59.6646628, 59.6654962, 59.6642813, 59.6636019, 59.6637434,
59.663465 , 59.6646862, 59.663324 ]),
'legendgroup': '',
'lon': array([10.7896737, 10.7887347, 10.7953659, 10.7922755, 10.7929767, 10.7932373,
10.7935577, 10.7908304, 10.7943351]),
'marker': {'color': 'fuchsia'},
'mode': 'markers',
'name': '',
'showlegend': False,
'subplot': 'mapbox',
'type': 'scattermapbox'}],
'layout': {'height': 600,
'legend': {'tracegroupgap': 0},
'mapbox': {'center': {'lat': 59.66422595555556, 'lon': 10.792331888888889},
'domain': {'x': [0.0, 1.0], 'y': [0.0, 1.0]},
'style': 'open-street-map',
'zoom': 14},
'margin': {'b': 0, 'l': 0, 'r': 0, 't': 0},
'template': '...',
'width': 700}
})
Streamsync integration#
Streamsync has handlers that easily connect interaction with reactive Python code.
Choropleths#
A pure choropleth can be plotted using a GeoJSON file, e.g., from https://norgeskart.no/json/norge/.
In addition a DataFrame containing the map region properties to use for colouring and hover information is needed.
# Choropleth map of US counties with unemployment rate
from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
counties = json.load(response)
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv",
dtype={"fips": str})
import plotly.express as px
fig_chl = px.choropleth(df, geojson=counties, locations='fips', color='unemp',
color_continuous_scale="Viridis",
range_color=(0, 12),
scope="usa",
labels={'unemp':'unemployment rate'}
)
fig_chl.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig_chl
#counties
# Gapminder dataset as a map
import plotly.express as px
df = px.data.gapminder()
fig_chl2 = px.choropleth(df, locations="iso_alpha", color="lifeExp", hover_name="country", animation_frame="year", range_color=[20,80])
fig_chl2
Show code cell content
# Dummy cell to ensure Plotly graphics are shown
import plotly.graph_objects as go
f = go.FigureWidget([go.Scatter(x=[1,1], y=[1,1], mode='markers')])