Mobility across US
Faceted median mobility of states as a Ridgeline Plot
Today we will make a graph that I just love - Ridgeline Plots. We will visualize the median mobility across US states as they appeared in the article by Axios : How the coronavirus pandemic changed mobility habits, by state
The data comes from Descartes Lab's GitHub Repository
import altair as alt
import pandas as pd
mobility_uri = 'https://raw.githubusercontent.com/descarteslabs/DL-COVID-19/master/DL-us-mobility-daterow.csv'
alt.renderers.set_embed_options(actions=False)
mobility = pd.read_csv(mobility_uri)
mobility.info()
mobility.head()
mobility_states = mobility[mobility['admin2'].isnull() & mobility['admin1'].notnull()]
mobility_states.head()
The data also contains the aggreagted median mobility for US as a country. We will filter that for our chart as we want only states -
#mobility_states.groupby('admin1')['m50_index'].max()
usa_mobility = mobility[mobility['admin2'].isnull() & mobility['admin1'].isnull()]
usa_mobility.head()
If you are interested in USA's mobility as a whole then you can visualize the following dataframe -
alt.data_transformers.enable('json')
#alt.data_transformers.enable('data_server')
I have taken the liberty to also color the facets by the median of the mobility values. To get it exactly like the chart by Axios, just remove the fill
encoding.
url = 'https://raw.githubusercontent.com/armsp/covidviz/master/assets/2020-08-31_Mobility_Data.json' # comment this when running locally
# url = mobility_states # uncomment this when running locally
highlight = alt.selection_single(on='mouseover', empty='all') # it looks like at present "facet" is not accepted as an encoding here even though it has been added as an encoding in a traditional sense of usage
alt.Chart(url, height=40, width=700,).mark_area().transform_window(
avg_m50 ='mean(m50_index)', frame=(-6,0), groupby=['fips']
).encode(
x=alt.X('date:T', title=None, axis=alt.Axis(domain=True, ticks=False, labels=True, format="%b", tickCount=5)),
y = alt.Y('avg_m50:Q', title=None, axis=None, scale=alt.Scale(range=[50, -100], zero=False),),#zero=False is important because of how vega-lite handles the range of data internally. When we used the raw values without averaging then it did not think that we may have negative values etc so the graph was not expanded for that. But when we did the averaging, somehow it decided to have some space for negative values, that's why your graph was pulled up from x-axis. By mentioning that we will not show zero or below values you manually fixed that range and the graph was pulled down as it was earlier.
fillOpacity= alt.condition(highlight, alt.value(0.8), alt.value(0.4)),
fill = alt.Fill(
'median(avg_m50):Q',
legend=None,
scale=alt.Scale(domain=[0,170],scheme='yellowgreenblue') #setting up domain gives favourable colours
),
facet = alt.Facet('admin1:N', title=None, columns=1, header=alt.Header(labelAngle=0, labelOrient='left', labelAlign='left', labelAnchor='middle'))
).configure_facet(spacing=0,).properties(bounds='flush', title='Median Mobility',).configure_view(stroke=None).configure_title(
anchor='middle'
).add_selection(highlight)