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
ShorthandFull nameExample
:QQuantitativeprice, temperature, count
:NNominalcolor, city name, category
:OOrdinalrating (low/medium/high), grade
:TTemporaldate, 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. :Q on 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
AggregateMeaning
mean, medianaverage / middle value
sumtotal
countnumber of rows
min, maxextremes
stdev, variancespread
distinctunique 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")

datum refers 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")

πŸ”— Next

Altair Interactivity Β· Altair Marks & Encodings