![]() |
![]() |
| NYT | The Economist |
|---|---|
![]() |
![]() |
Altair is a declarative statistical visualization library for Python, based on Vega-Lite and the Grammar of Graphics paradigm.
Vega-Lite is a high-level grammar of interactive graphics.
| JSON Spec | Output Plot |
|---|---|
![]() |
![]() |
Declare What instead of implementing How

mark_area - Area chartsmark_bar - Bar charts mark_point - Scatterplotsmark-geoshape - Mapsmark_line - Line Chartsmark_rule - Horizontal and Vertical Linesmark_rect - Heatmapsmark_text - Text Chartsmark_boxplot - Box Plotsmark_errorbar - Errorbar around a pointmark_errorband - Errorband around a linexylongitudelatitudecolorsizetooltipcolumnrowfacet| Data Type | Shorthand Code | Description |
|---|---|---|
| quantitative | Q |
a continuous real-valued quantity |
| ordinal | O |
a discrete ordered quantity |
| nominal | N |
a discrete unordered category |
| temporal | T |
a time or date value |
| geojson | G |
a geographic shape |

import altair as alt
import pandas as pd
weather_data = "https://github.com/vega/vega-datasets/blob/master/data/weather.csv?raw=True"
data = pd.read_csv(weather_data)
data['date'] = pd.to_datetime(data['date'])
data.head()
| location | date | precipitation | temp_max | temp_min | wind | weather | |
|---|---|---|---|---|---|---|---|
| 0 | Seattle | 2012-01-01 | 0.0 | 12.8 | 5.0 | 4.7 | drizzle |
| 1 | Seattle | 2012-01-02 | 10.9 | 10.6 | 2.8 | 4.5 | rain |
| 2 | Seattle | 2012-01-03 | 0.8 | 11.7 | 7.2 | 2.3 | rain |
| 3 | Seattle | 2012-01-04 | 20.3 | 12.2 | 5.6 | 4.7 | rain |
| 4 | Seattle | 2012-01-05 | 1.3 | 8.9 | 2.8 | 6.1 | rain |
alt.Chart(data).mark_point().encode(
x = 'date',
y = 'temp_max',
column = 'location'
)
Let's give different colors to each location
alt.Chart(data).mark_point().encode(
x = 'date',
y = 'temp_min',
column = 'location',
color = 'location'
)
I wonder what the distribution of temperature_maximum is for both locations? How do we arrive at that? Well x axis stays the same, on y axis we say the count of temp_max and we do not facet!
alt.Chart(data).mark_bar().encode(
x = 'temp_max',
y = 'count(temp_max)'
)
scatter = alt.Chart(data).mark_point().encode(
x = 'precipitation',
y = 'wind'
)
regression = alt.Chart(data).transform_regression('precipitation', 'wind').mark_line().encode(
x = 'precipitation',
y = 'wind'
)
scatter | regression
scatter + regression.mark_line(color="red")
import altair as alt
import pandas as pd
import geopandas as gpd
us_covid_data_uri = 'https://github.com/nytimes/covid-19-data/blob/master/us-counties.csv?raw=true'
raw_data = pd.read_csv(us_covid_data_uri)
raw_data['date'] = pd.to_datetime(raw_data['date'])
covid = raw_data.copy()
covid.head()
| date | county | state | fips | cases | deaths | |
|---|---|---|---|---|---|---|
| 0 | 2020-01-21 | Snohomish | Washington | 53061.0 | 1 | 0 |
| 1 | 2020-01-22 | Snohomish | Washington | 53061.0 | 1 | 0 |
| 2 | 2020-01-23 | Snohomish | Washington | 53061.0 | 1 | 0 |
| 3 | 2020-01-24 | Cook | Illinois | 17031.0 | 1 | 0 |
| 4 | 2020-01-24 | Snohomish | Washington | 53061.0 | 1 | 0 |
county_shpfile = './cb_2019_us_county_20m'
county = gpd.read_file(county_shpfile)
We need to have longitude and latitude so that the marks are positioned where they are supposed to be
county['lon'] = county['geometry'].centroid.x
county['lat'] = county['geometry'].centroid.y
<class 'geopandas.geodataframe.GeoDataFrame'>
RangeIndex: 3220 entries, 0 to 3219
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 fips 3220 non-null int64
1 geometry 3220 non-null geometry
2 lon 3220 non-null float64
3 lat 3220 non-null float64
dtypes: float64(2), geometry(1), int64(1)
memory usage: 100.8 KB
alt.Chart(county).mark_geoshape().encode().properties(width=800, height=600)
alt.Chart(county).mark_geoshape().encode().properties(width=800, height=600).project('albersUsa')