Vega

Vega is a visualization grammar rather than a chart library: you describe scales, marks and encodings, and it draws whatever you specified.

Reach for it when Vega-Lite cannot express what you need. For ordinary charts, Vega-Lite is a fraction of the work.


#What it is good at

  • Custom visualizations with no standard chart equivalent.

  • Layered or composite charts needing precise control.

  • Anything where the default chart types genuinely do not fit.


#What it draws

Diagram

Syntax starts with

Data

"data": [{"name": "table", "values": [...]}]

Scales

"scales": [{"name": "x", "type": "band", ...}]

Axes

"axes": [{"orient": "bottom", "scale": "x"}]

Marks

"marks": [{"type": "rect", "encode": {...}}]


#A worked example

A bar chart written out in full Vega, scales and all:

Vega

The source, which you can paste into a new diagram and edit:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 360,
  "height": 200,
  "padding": 5,
  "data": [{
    "name": "table",
    "values": [
      {"stage": "Open", "count": 48},
      {"stage": "In progress", "count": 31},
      {"stage": "Blocked", "count": 12},
      {"stage": "Done", "count": 74}
    ]
  }],
  "scales": [
    {"name": "x", "type": "band", "domain": {"data": "table", "field": "stage"}, "range": "width", "padding": 0.2},
    {"name": "y", "type": "linear", "domain": {"data": "table", "field": "count"}, "range": "height", "nice": true}
  ],
  "axes": [
    {"orient": "bottom", "scale": "x"},
    {"orient": "left", "scale": "y"}
  ],
  "marks": [{
    "type": "rect",
    "from": {"data": "table"},
    "encode": {
      "enter": {
        "x": {"scale": "x", "field": "stage"},
        "width": {"scale": "x", "band": 1},
        "y": {"scale": "y", "field": "count"},
        "y2": {"scale": "y", "value": 0}
      }
    }
  }]
}

#A few things that catch people out

  • The $schema URL is how Vega and Vega-Lite are told apart. Keep it.

  • Data is embedded in the spec, so the chart is a snapshot. Date it.

  • Interactive signals do not survive as a static rendering.



Learn one properly. Borrow the rest when you need them.