I am able to generate a world choropleth map with tooltips on mouseover and click selection to grey out unselected countries. I would like to be able to click on a country and have the map pan and zoom in. I have figured out how to use lon/lat centroids for each country and manually change the scale/lon/lat to pan and zoom, but I am struggling how to change lon/lat via the selection method so a user can click on a country to zoom in (also, I would need to be able to zoom back to the default full view somehow). Is it possible somehow to use transform_calculate
or something to assign values to lon/lat? Thanks.
(map data is from naturalearthdata)
import altair as alt
import geopandas as gpd
import json
import numpy as np
world_shp = gpd.read_file('data_world/ne_110m_admin_0_countries.shp')[['ADMIN', 'geometry']]
world_shp.rename(columns={'ADMIN': 'Country'}, inplace=True)
world_shp = world_shp.drop(159) # remove antarctica
world_shp.sort_values(by='Country')
# Add centroids
world_shp['centroid_lon'] = world_shp['geometry'].centroid.x
world_shp['centroid_lat'] = world_shp['geometry'].centroid.y
# Add column to map_df of some dummy data to plot
dummy = np.random.randint(10, 1000, len(world_shp))
world_shp['Cases'] = dummy
# Setup data
world_json = json.loads(world_shp.to_json())
world_data = alt.Data(values=world_json['features'])
# Plotting:
selection = alt.selection_single(fields=['properties.Cases'])
color = alt.condition(
selection,
alt.Color('properties.Cases',
type='quantitative',
scale=alt.Scale(scheme='bluegreen')),
alt.value('lightgray')
)
# Add Choropleth Layer
world = alt.Chart(world_data).mark_geoshape().encode(
color=color,
tooltip=['properties.Country:O', 'properties.Cases:Q']
).properties(
width=600,
height=400
).add_selection(
selection
)
# Add top layer to mark boundaries
boundaries = alt.Chart(world_data, title='Title Here').mark_geoshape(
stroke='white',
strokeWidth=1,
fill=None
)
world + boundaries
And the manual method to pan/zoom:
centroid = 'China'
lon = world_shp[world_shp['Country'] == centroid]['centroid_lon'].iloc[0]
lat = world_shp[world_shp['Country'] == centroid]['centroid_lat'].iloc[0]
world.project(
scale=250,
center=[lon, lat]
)
The dataframe looks like this: