Take back control … of your data visualisations

Most local government employees reach for spreadsheets when they need to create a chart. However, spreadsheet programs can reinforce bad visualisation practices by not making the process required to build a graphic explicit. Chart templates provide quick and easy ways to create a graphic but they teach little about how visualisations are constructed or how they encode data.

In this article, we recommend Vega-Lite because it allows users to quickly build visually appealing static and interactive data visualisations in their web browser. No additional software is required, it’s open source, based on the principles of good visualisation design, and promotes reproducibility with graphics created in shareable code.

Vega-Lite

Vega-Lite is an open source language for quickly creating data visualisations for the web. Developed by the University of Washington's Interactive Data Lab and released in 2016, visualisations are built using high-level specifications which map data to graphical marks (bars, points, lines etc.) with low-level details like axes, scales, and legends added automatically. This simplified syntax enables users to rapidly build and iterate between exploratory data visualisations. The specifications are written in JSON (JavaScript Object Notation) which encourages sharing and reproducibility.

Like the ggplot2 R package, Vega-Lite is an implementation of Leland Wilkinson’s “Grammar of Graphics” (1999, 2005), a framework for articulating the component elements of graphics. These components are explicit in the Vega-Lite specification used to construct graphics.

  • Data are read inline or via a URL in .json or .csv format.
  • These data can then be optionally modified by filtering, aggregating, or by some other common transformation.
  • A mark like a bar, point, or line is then chosen to visually encode the data to.
  • These encodings then determine how to map the data to the properties of these visual marks e.g. position (x, y), size, and colour.

An example

The following example will show you how to build a simple data visualisation in Vega-Lite. Remember that you can follow along by pasting the code into Vega-Lite’s online editor.

Data

We have an excerpt of data from speedofanimals.com which describes the top speed of selected land animals in kilometres per hour.

This dataset can be fed inline as a JSON array:

[
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]

or loaded via a URL in formats such as .json, .tsv and .csv. We are using inline data in this example so the array needs to be mapped to the data property of a new object:

{
"data": {
"values": [
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]
}
}

Transformation

The data are then transformed using calculate to convert speed from kilometre per hour (kph) to miles per hour (mph).

{
"data": {
"values": [
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]
},
"transform": [{"calculate": "datum.kph*0.62137", "as": "mph"}]
}

Marks

We want to display the data as a bar chart so we next need to specify bar as the mark. Other available marks include point, circle, area and text.

{
"data": {
"values": [
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]
},
"transform": [{"calculate": "datum.kph*0.62137", "as": "mph"}],
"mark": "bar"
}
A “bar” mark

Encoding

Then we need to map the data to the properties of the chosen mark. Each variable that needs to be mapped requires the field to be named and the type (e.g. quantitative, nominal, ordinal, or temporal) defined.

{
"data": {
"values": [
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]
},
"transform": [{"calculate": "datum.kph*0.62137", "as": "mph"}],
"mark": "bar",
"encoding": {
"x": {"field": "mph", "type": "quantitative"},
"y": {"field": "animal", "type": "nominal"}
}
}
A simple bar chart

Sort

Then we need to sort the order of the scale domain so that it is easier for viewers to see the fastest and slowest speeds.

{
"data": {
"values": [
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]
},
"transform": [{"calculate": "datum.kph*0.62137", "as": "mph"}],
"mark": "bar",
"encoding": {
"x": {"field": "mph", "type": "quantitative"},
"y": {
"field": "animal",
"type": "nominal",
"sort": {"field": "mph", "op": "average", "order": "descending"}
}
}
}
Chart, sorted!

Finishing touches

With some tweaks to the width, axis labelling, colours and the addition of some custom tooltips we have a simple, well designed bar chart with some interactivity.

{
"width": 300,
"title": {"text": "Top speeds of selected land animals"},
"data": {
"values": [
{"animal": "Cheetah", "kph": 120},
{"animal": "Domestic Cat", "kph": 48},
{"animal": "Elephant", "kph": 40},
{"animal": "Giraffe", "kph": 52},
{"animal": "Horse", "kph": 88},
{"animal": "Ostrich", "kph": 70},
{"animal": "Pig", "kph": 17.7},
{"animal": "Polar Bear", "kph": 30},
{"animal": "Rabbit", "kph": 48},
{"animal": "Squirrel", "kph": 20}
]
},
"transform": [{"calculate": "datum.kph*0.62137", "as": "mph"}],
"mark": "bar",
"encoding": {
"x": {
"field": "mph",
"type": "quantitative",
"axis": {"title": "Speed (mph)"}
},
"y": {
"field": "animal",
"type": "nominal",
"sort": {"field": "mph", "op": "average", "order": "descending"},
"axis": {"title": null}
},
"color": {"value": "#fc6721"},
"opacity": {"value": 0.7},
"tooltip": [
{"field": "animal", "type": "nominal", "title": "Animal"},
{
"field": "mph",
"type": "quantitative",
"title": "Speed",
"format": ".1f"
}
]
}
}
An interactive bar chart

This chart can then be exported in PNG or SVG format using the Vega-Lite online editor. If you want to retain the interactivity you’ll need to save the code in a JSON file and embed it within a web page using HTML. Have a look at the example here.

This bar chart only scratches the surface of what Vega-Lite can do. Check out the examples page for inspiration and code that you can adapt.

Final thoughts

In a recent article, Robin Linacre, a data scientist at the UK’s Ministry of Justice proposed Vega-Lite as a ‘sensible default’ (Linacre, 2018) for data visualisation, particularly in the public sector. We wholeheartedly agree for two primary reasons: 1) Vega-Lite articulates the principles of good visualisation design explicitly in its specifications and; 2) requires nothing more than a modern web browser to use. Go visualise!

References

Satyanarayan, A., Moritz, D., Wongsuphasawat, K., & Heer, J. (2017). Vega-Lite: A grammar of interactive graphics. IEEE Transactions on Visualization and Computer Graphics, 23(1):341–350.

Wongsuphasawat, K., Moritz, D., and Satyanarayan, A., (2017). Vega Lite: A Grammar of Interactive Graphics. Video of presentation from OpenVis Conf talk.

Linacre, R. (2018). Why I’m backing Vega-Lite as our default tool for data visualisation. Medium.

UW Interactive Data Lab (2017). Introducing Vega-Lite 2.0. Medium.