Search code examples
python-3.xvegaaltairvega-lite

Overlay state outlines on choropleth in Altair


I am unable to overlay state outlines over a county level choropleth in Altair.
I am using altair's layer method to achieve this.
However, it is taking the stroke color of the state outline chart and drawing county outlines with that color.

This is my code:

import altair as alt
from vega_datasets import data

us_states = alt.topo_feature(data.us_10m.url, 'states')
us_counties = alt.topo_feature(data.us_10m.url, 'counties')
unemp_data = data.unemployment(sep='\t')
unemp_data.head()

plot = alt.Chart(us_counties).mark_geoshape(stroke='white').project(
type='albersUsa'
).transform_lookup(
    lookup='id',
    from_=alt.LookupData(unemp_data, 'id', ['rate'])
).encode(
    color='rate:Q'
).properties(
    width=700,
    height=400
)

outline = alt.Chart(us_states).mark_geoshape( stroke='black').project(
    type='albersUsa'
).properties(
    width=700,
    height=400
)

alt.layer(plot,outline)

I am getting the following result: Layered Plot


Solution

  • This looks to be a bug in Vega, wherein if two data sources are identical the stroke properties overwrite each other. I managed to work around this by adding a "#" to the end of one of the URLs to trick Vega into thinking the datasets are different:

    import altair as alt
    from vega_datasets import data
    
    us_states = alt.topo_feature(data.us_10m.url, 'states')
    us_counties = alt.topo_feature(data.us_10m.url+"#", 'counties')
    unemp_data = data.unemployment.url
    
    plot = alt.Chart(us_counties).mark_geoshape(stroke='white').project(
    type='albersUsa'
    ).transform_lookup(
        lookup='id',
        from_=alt.LookupData(unemp_data, 'id', ['rate'])
    ).encode(
        color='rate:Q'
    ).properties(
        width=700,
        height=400
    )
    
    outline = alt.Chart(us_states).mark_geoshape(stroke='black', fillOpacity=0).project(
        type='albersUsa'
    ).properties(
        width=700,
        height=400
    )
    
    alt.layer(plot,outline)
    

    enter image description here

    (Additionally, I specified fillOpacity=0 because this default is going to change in Vega-Lite 4).