Filling country colours by value of column in other DataFrame
See original GitHub issueHi,
I’ve just started experimenting with Altair, and am loving it so far. I am, however, struggling somewhat with generating map plots.
Problem
I’m trying to plot a world map of confirmed Covid-19 cases, using data provided by John Hopkins. I want to colour countries by the number of confirmed cases, but have been unsuccessful.
Data
The code to retrieve and clean the data is:
import janitor # pip install pyjanitor
import pandas as pd
CASES_WORLDWIDE = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/web-data/data/cases_country.csv"
def get_worldwide_cases(url: str = CASES_WORLDWIDE):
cases = pd.read_csv(url)
cleaned = (
cases.clean_names()
.rename_column("long_", "lon")
.transform_column("last_update", lambda x: pd.to_datetime(x).normalize())
)
return cleaned
world_source = get_worldwide_cases()
The head of the data will look like this:
country_region | last_update | lat | lon | confirmed | deaths | recovered | active | |
---|---|---|---|---|---|---|---|---|
0 | Australia | 2020-03-27 00:00:00 | -25 | 133 | 3143 | 13 | 194 | 2936 |
1 | Austria | 2020-03-27 00:00:00 | 47.5162 | 14.5501 | 7317 | 58 | 225 | 7034 |
2 | Canada | 2020-03-27 00:00:00 | 60.001 | -95.001 | 4046 | 40 | 184 | 0 |
3 | China | 2020-03-27 00:00:00 | 30.5928 | 114.305 | 81897 | 3296 | 74720 | 3881 |
4 | Denmark | 2020-03-27 00:00:00 | 56 | 10 | 2163 | 52 | 57 | 2054 |
Desired output
I would like to produce a plot that looks something like this:
Current output
Since I’ve been unable to reproduce the above plot, I hacked together a workaround that displays the information in a different way. My current output looks like this:
Current solution
The code that produces my plot is:
# Get data
import altair as alt
from vega_datasets import data
# Map plot
source = alt.topo_feature(data.world_110m.url, "countries")
base_map = (
alt.Chart(source)
.mark_geoshape(fill="white", stroke="gray")
.properties(width=600, height=300)
.project("naturalEarth1")
)
points = (
alt.Chart(world_source)
.mark_point()
.encode(
latitude="lat",
longitude="lon",
fill=alt.value("red"),
size="confirmed:Q",
stroke=alt.value(None),
)
)
final_map = (
(base_map + points)
.configure_view(strokeWidth=0)
.configure_mark(opacity=0.5,)
)
I’ve understood that using .transform_lookup()
is one possible way to solve this, but all attempts at looking up the confirmed
column in world_source
have failed so far.
I would greatly appreciate any input!
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
Hi @jakevdp, thanks for the reply and useful tips.
You were right, it was just a matter of finding the appropriate ISO 3166-1 codes and performing a lookup on them. This is the (preliminary) result:
In case anyone is interested, this is the code to generate the plot above. It assumes that we have defined a lookup dataset (in my case
world_source
) with the required ISO 3166-1 codes.Thanks again @jakevdp, stay safe.
@ThelmaSilva et al., here’s a full working example with the current data: