Skip to content

Shorthand ^0.4.2

The most concise form of Plot is its shorthand syntax where no options are specified — only data. To use this shorthand, the data must have a specific structure: either a one-dimensional array of values [v₀, v₁, v₂, …] or a two-dimensional array of tuples [[x₀, y₀], [x₁, y₁], [x₂, y₂], …].

While none of these charts are particularly groundbreaking, we hope you find this shorthand convenient the next time you want a quick look at some data. And if the shorthand view is useful, you can then enhance it by adding options!

One dimension

Let’s start with the one-dimensional form: an array of numbers.

js
numbers = [
  170.16, 172.53, 172.54, 173.44, 174.35, 174.55, 173.16, 174.59, 176.18, 177.90,
  176.15, 179.37, 178.61, 177.30, 177.30, 177.25, 174.51, 172.00, 170.16, 165.53,
  166.87, 167.17, 166.00, 159.10, 154.83, 163.09, 160.29, 157.07, 158.50, 161.95,
  163.04, 169.79, 172.36, 172.05, 172.83, 171.80, 173.67, 176.35, 179.10, 179.26
]

These numbers represent the daily opening price of Apple stock starting on January 1, 2018. For a simple line chart, we can pass the data to Plot.lineY to construct a line mark, and then call line.plot.

15615816016216416616817017217417617805101520253035Fork
js
Plot.lineY(numbers).plot()

The y-axis above represents price in U.S. dollars. The x-axis represents the index of the data: the first value 170.16 is shown at x = 0, the second value 172.53 at x = 1, and so on. In other words, x represents the number of (trading) days since January 1, 2018. It’d be nicer to have an x-axis that shows dates here, but it’s still convenient to see the trend in stock price quickly.

If we pass the numbers to Plot.areaY instead, we’ll get a simple area chart with a baseline implicitly at y = 0.

02040608010012014016005101520253035Fork
js
Plot.areaY(numbers).plot()

Similarly if we use Plot.rectY, we’ll get a series of vertical bars. This implicitly uses the interval transform such that the first rect spans from x = 0 to x = 1, the second from x = 1 to x = 2, and so on, with a horizontal inset to separate adjacent rects.

0204060801001201401600510152025303540Fork
js
Plot.rectY(numbers).plot()

Plot.barY produces a visually similar result but with different semantics: x is now ordinal (a band scale) rather than quantitative (linear). An ordinal axis labels every tick, which appear at the middle of each bar rather than between rects.

0204060801001201401600123456789101112131415161718192021222324252627282930313233343536373839Fork
js
Plot.barY(numbers).plot()

Like Plot.barY, Plot.cellX implies that x is ordinal. But now instead of a y channel the numeric value is encoded as the fill color. The default quantitative color scheme is turbo; higher values are reddish, and lower values blueish.

0123456789101112131415161718192021222324252627282930313233343536373839Fork
js
Plot.cellX(numbers).plot()

If we don’t care about the order of our data and we instead just want to look at the one-dimensional distribution of values, we can use Plot.dotX.

156158160162164166168170172174176178Fork
js
Plot.dotX(numbers).plot()

Alternatively, we can use Plot.ruleX to draw a vertical rule at each value. In this case, Plot.ruleX behaves identically to Plot.tickX. (If there were a y channel, then Plot.tickX would imply that y is ordinal whereas Plot.ruleX would imply that y is quantitative.) It is common to use the rule shorthand to annotate special x or y values in plots, such as y = 0, in conjunction with other marks.

156158160162164166168170172174176178Fork
js
Plot.ruleX(numbers).plot()
156158160162164166168170172174176178Fork
js
Plot.tickX(numbers).plot()

We could even use Plot.vectorX here to draw little up-pointing arrows. (Typically the vector mark is used in conjunction with the rotate and length options to control the direction and magnitude of each vector.)

156158160162164166168170172174176178Fork
js
Plot.vectorX(numbers).plot()

While not particularly readable due to occlusion, we can use Plot.textX to draw a label at each value, too.

156158160162164166168170172174176178170.16172.53172.54173.44174.35174.55173.16174.59176.18177.9176.15179.37178.61177.3177.3177.25174.51172170.16165.53166.87167.17166159.1154.83163.09160.29157.07158.5161.95163.04169.79172.36172.05172.83171.8173.67176.35179.1179.26Fork
js
Plot.textX(numbers).plot()

For a more formal method of summarizing a one-dimensional distribution, we can use Plot.boxX to create a horizontal boxplot. The gray band represents the interquartile range; the black whiskers show the extrema (not including outliers); and the thick black stroke represents the median; any outliers (none in this dataset) are drawn as dots.

156158160162164166168170172174176178Fork
js
Plot.boxX(numbers).plot()

Some of Plot’s transforms support shorthand syntax, too. For example, we can use Plot.rectY with Plot.binX to generate a histogram — another common way to visualize a one-dimensional distribution.

0246810121416↑ Frequency150155160165170175180Fork
js
Plot.rectY(numbers, Plot.binX()).plot()

Similarly Plot.groupX can be used to group and count ordinal data, such as the frequency of bases in a random DNA sequence.

js
gene = "AAAAGAGTGAAGATGCTGGAGACGAGTGAAGCATTCACTTTAGGGAAAGCGAGGCAAGAGCGTTTCAGAAGACGAAACCTGGTAGGTGCACTCACCACAG"
05101520253035↑ FrequencyACGTFork
js
Plot.barY(gene, Plot.groupX()).plot()

And here’s the dodge transform for a beeswarm plot:

156158160162164166168170172174176178Fork
js
Plot.dotX(numbers, Plot.dodgeY()).plot()

Two dimensions

Now let’s switch to a two-dimensional array of tuples [[x₀, y₀], [x₁, y₁], [x₂, y₂], …]. The x-values here are times (Date instances at UTC midnight); the y-values again are the daily opening price of Apple stock.

js
timeSeries = [
  [new Date("2018-01-02"), 170.160004],
  [new Date("2018-01-03"), 172.529999],
  [new Date("2018-01-04"), 172.539993],
  [new Date("2018-01-05"), 173.440002],
  [new Date("2018-01-08"), 174.350006],
  [new Date("2018-01-09"), 174.550003],
  [new Date("2018-01-10"), 173.160004],
  [new Date("2018-01-11"), 174.589996],
  [new Date("2018-01-12"), 176.179993],
  [new Date("2018-01-16"), 177.899994],
  [new Date("2018-01-17"), 176.149994],
  [new Date("2018-01-18"), 179.369995],
  [new Date("2018-01-19"), 178.610001],
  [new Date("2018-01-22"), 177.300003],
  [new Date("2018-01-23"), 177.300003],
  [new Date("2018-01-24"), 177.250000],
  [new Date("2018-01-25"), 174.509995],
  [new Date("2018-01-26"), 172.000000],
  [new Date("2018-01-29"), 170.160004],
  [new Date("2018-01-30"), 165.529999],
  [new Date("2018-01-31"), 166.869995],
  [new Date("2018-02-01"), 167.169998],
  [new Date("2018-02-02"), 166.000000],
  [new Date("2018-02-05"), 159.100006],
  [new Date("2018-02-06"), 154.830002],
  [new Date("2018-02-07"), 163.089996],
  [new Date("2018-02-08"), 160.289993],
  [new Date("2018-02-09"), 157.070007],
  [new Date("2018-02-12"), 158.500000],
  [new Date("2018-02-13"), 161.949997],
  [new Date("2018-02-14"), 163.039993],
  [new Date("2018-02-15"), 169.789993],
  [new Date("2018-02-16"), 172.360001],
  [new Date("2018-02-20"), 172.050003],
  [new Date("2018-02-21"), 172.830002],
  [new Date("2018-02-22"), 171.800003],
  [new Date("2018-02-23"), 173.669998],
  [new Date("2018-02-26"), 176.350006],
  [new Date("2018-02-27"), 179.100006],
  [new Date("2018-02-28"), 179.259995]
]

If we pass this to Plot.line (not Plot.lineY as before), we’ll get another line chart, but now the x-axis shows the date rather than the zero-based index. Also, the x-values are no longer uniformly spaced, as there are gaps on the weekends and holidays when the markets are closed.

1561581601621641661681701721741761787Jan1421284Feb111825Fork
js
Plot.line(timeSeries).plot()

Similarly Plot.area will produce the equivalent area chart, again with an implicit baseline at y = 0.

0204060801001201401607Jan1421284Feb111825Fork
js
Plot.area(timeSeries).plot()

There’s currently no two-dimensional shorthand for rect or bar, though you can use these marks to display time series data with options.

Plot.dot will produce a scatterplot…

1561581601621641661681701721741761787Jan1421284Feb111825Fork
js
Plot.dot(timeSeries).plot()

As will Plot.vector…

1561581601621641661681701721741761787Jan1421284Feb111825Fork
js
Plot.vector(timeSeries).plot()

Plot.text also produces a scatterplot with labels showing the zero-based index of the data. Perhaps not very useful, but it at least shows the data’s order.

1561581601621641661681701721741761787Jan1421284Feb1118250123456789101112131415161718192021222324252627282930313233343536373839Fork
js
Plot.text(timeSeries).plot()

Plot.cell also supports two-dimensional shorthand. As we saw above, Plot.cell implies that x and y are ordinal, so we shouldn’t pass temporal (dates) and quantitative (numbers) data; here’s a matrix diagram that shows which pairs exist in the dataset. You might use this, for example, to visualize who reviewed whose code.

js
matrix = [
  ["Jacob", "Olivia"],
  ["Mia", "Noah"],
  ["Noah", "Ava"],
  ["Ava", "Mason"],
  ["Olivia", "Noah"],
  ["Jacob", "Emma"],
  ["Ava", "Noah"],
  ["Noah", "Jacob"],
  ["Olivia", "Ava"],
  ["Mason", "Emma"],
  ["Jacob", "Mia"],
  ["Mia", "Jacob"],
  ["Emma", "Jacob"]
]
AvaEmmaJacobMasonMiaNoahOliviaAvaEmmaJacobMasonMiaNoahOliviaFork
js
Plot.cell(matrix).plot()

Caveats

Plot has a few marks that don’t currently provide meaningful shorthand. The arrow and link marks both require a start (x1, y1) and end (x2, y2) point; and the image mark requires a source URL (src).