Altair Data Types & Transformations
π€ The four core data types
"column:Q" # Quantitative β numeric, continuous
"column:N" # Nominal β categories, no order
"column:O" # Ordinal β categories, WITH order
"column:T" # Temporal β dates/times| Shorthand | Full name | Example |
|---|---|---|
:Q | Quantitative | price, temperature, count |
:N | Nominal | color, city name, category |
:O | Ordinal | rating (low/medium/high), grade |
:T | Temporal | date, timestamp |
alt.X("category", type="nominal") # explicit long form, same as "category:N"Wrong type = wrong chart.
:O(ordinal) on a category sorts it in the given order;:N(nominal) sorts alphabetically by default.:Qon something that's really a category produces a nonsensical continuous axis.
ποΈ Temporal formatting
alt.X("date:T", timeUnit="month") # aggregate/bin by month
alt.X("date:T", timeUnit="yearmonth") # year + month
alt.X("date:T", axis=alt.Axis(format="%b %Y")) # custom date format on the axisπ Aggregation
alt.Chart(df).mark_bar().encode(
x="category:N",
y="mean(value):Q" # aggregate inline via string shorthand
)alt.Y("value:Q", aggregate="mean") # explicit form, same result| Aggregate | Meaning |
|---|---|
mean, median | average / middle value |
sum | total |
count | number of rows |
min, max | extremes |
stdev, variance | spread |
distinct | unique value count |
alt.Chart(df).mark_bar().encode(x="category:N", y="count():Q") # count() needs no field nameπ¦ Binning (histograms)
alt.Chart(df).mark_bar().encode(
x=alt.X("value:Q", bin=True),
y="count():Q"
)
alt.X("value:Q", bin=alt.Bin(maxbins=30)) # control bin countπ Filtering
alt.Chart(df).mark_bar().transform_filter(
"datum.value > 100"
).encode(x="category:N", y="value:Q")
alt.Chart(df).mark_bar().transform_filter(
alt.FieldGTPredicate(field="value", gt=100) # equivalent, object form
).encode(x="category:N", y="value:Q")
datumrefers to a single data row inside a transform expression β Vega-Lite's own JS-like expression syntax, not Python.
β Calculated fields
alt.Chart(df).transform_calculate(
profit_margin="datum.profit / datum.revenue"
).mark_point().encode(x="revenue:Q", y="profit_margin:Q")π½ Sorting
alt.X("category:N", sort="-y") # sort x-axis by descending y value
alt.X("category:N", sort=["C","A","B"]) # explicit custom order
alt.Y("category:N", sort=alt.EncodingSortField(field="value", order="descending"))πͺ Windowing (running totals, ranks)
alt.Chart(df).transform_window(
cumulative_total="sum(value)",
sort=[{"field": "date"}]
).mark_line().encode(x="date:T", y="cumulative_total:Q")