3  Reading practice

Can you say what a plot will look like from its sentence alone? The last chapter gave you the vocabulary, and this one practices reading with it. Ten plots follow, ending in a cube. For each one, read the sentence aloud before looking at the picture, then check the picture against what you said. The sentence read aloud is given under each plot. Try to say it yourself first.

3.1 Gold medals by country

Which country won the most gold, and by how much? medals holds one row per country, with its counts of gold, silver and bronze:

medals: all 5 rows
country gold silver bronze
USA 46 37 38
China 38 31 22
Great Britain 29 17 19
Russia 19 18 9
Germany 17 10 15
data(medals) + bar + x(country) + y(gold)
data(medals) + bar + x(col.country) + y(col.gold)
data(medals) + bar + x(:country) + y(:gold)
plot(data(medals), bar, x(col.country), y(col.gold))
USA China Great Britain Russia Germany 0 10 20 30 40 Gold Country

“Given the medals: bars, x is country, y is gold.” A bar measures an amount from zero, so the amount needs a continuous axis and the category takes the other one. The bindings put countries on x and gold on y. There is no transform here. bar draws the numbers exactly as the table gives them.

3.2 The same bars, horizontal

A medal table is usually printed as a list, with the leader at the top. The same five counts can be read that way. medals already lists the countries by gold, and the first row is drawn at the top, so the leader comes first.

data(medals) + bar + x(gold) + y(country)
data(medals) + bar + x(col.gold) + y(col.country)
data(medals) + bar + x(:gold) + y(:country)
plot(data(medals), bar, x(col.gold), y(col.country))
0 10 20 30 40 Germany Russia Great Britain China USA Country Gold

“Given the medals: bars, x is gold, y is country.” Put the category on the vertical axis and the amount on the horizontal one, and the bars become horizontal. There is no “horizontal bar” atom, and no argument that turns the bars. The sentence already says which axis holds the category, so the orientation follows from the bindings.

3.3 One measurement’s shape

The first two plots drew five counts that were already in the table. Often a table holds only measurements, and no counts.

Do petal lengths gather around one typical value, or do they separate into groups? One column, petal length, answers that, and it comes from a new table. iris_flowers holds one row per flower: three measurements (sepal length, sepal width and petal length), and the species the flower belongs to.

iris_flowers: first 5 of 150 rows
sepal_length sepal_width petal_length species
5.1 3.5 1.4 setosa
4.9 3.0 1.4 setosa
4.7 3.2 1.3 setosa
4.6 3.1 1.5 setosa
5.0 3.6 1.4 setosa
data(iris_flowers) + bar * bin + x(petal_length)
data(iris_flowers) + bar * bin + x(col.petal_length)
data(iris_flowers) + bar * bin + x(:petal_length)
plot(data(iris_flowers), layer(bar, bin), x(col.petal_length))
2 4 6 0 10 20 30 40 Count Petal Length

“Given the iris flowers: bars derived by bin, x is petal length.” The * attaches the transform bin to bar. bin divides the axis into bins and counts the rows in each, and bar draws one bar per bin. A plot like this is a histogram. You did not bind y. bin writes the counts itself, so the y axis is labeled Count. Note the two peaks. Plot eight explains them.

3.4 The same question, smoothly

A histogram draws the distribution as flat-topped bars, one per bin, and sometimes you want one smooth curve instead. The measurement this time is life expectancy, across the 142 countries in gapminder_2007.

gapminder_2007: first 5 of 142 rows
country continent year life population gdp
Afghanistan Asia 2007 43.828 31889923 974.5803
Albania Europe 2007 76.423 3600523 5937.0295
Algeria Africa 2007 72.301 33333216 6223.3675
Angola Africa 2007 42.731 12420476 4797.2313
Argentina Americas 2007 75.320 40301927 12779.3796
data(gapminder_2007) + line * density + x(life)
data(gapminder_2007) + line * density + x(col.life)
data(gapminder_2007) + line * density + x(:life)
plot(data(gapminder_2007), layer(line, density), x(col.life))
40 60 80 0.00 0.01 0.02 0.03 0.04 Density Life

“Given gapminder 2007: a line derived by density, x is life.” The question is the same as the histogram’s: how is this measurement distributed? The answer is drawn differently. density replaces bin, and line replaces bar, because a smooth estimate is one curve, not many bars.

3.5 One strip of dots per continent

The density curve in plot four reduced 142 countries to one shape. Do the continents differ in life expectancy, and how widely do the countries inside each one vary? Both answers are visible when every country is shown.

data(gapminder_2007) + point + x(continent) + y(life)
data(gapminder_2007) + point + x(col.continent) + y(col.life)
data(gapminder_2007) + point + x(:continent) + y(:life)
plot(data(gapminder_2007), point, x(col.continent), y(col.life))
Asia Europe Africa Americas Oceania 40 50 60 70 80 Life Continent

“Given gapminder 2007: points, x is continent, y is life.” A categorical x gives each category a slot on the axis, and that category’s points are drawn in a vertical strip at that slot. The same rule placed bars on country slots in plot one. Here it applies to a different mark. A plot shaped like this one has a name: the strip plot.

3.6 The typical value per continent

You often want one number per continent, its average, instead of 142 separate values.

data(gapminder_2007) + bar * mean + x(continent) + y(life)
data(gapminder_2007) + bar * mean + x(col.continent) + y(col.life)
data(gapminder_2007) + bar * mean + x(:continent) + y(:life)
plot(data(gapminder_2007), layer(bar, mean), x(col.continent),
  y(col.life))
Asia Europe Africa Americas Oceania 0 20 40 60 80 Life Continent

“Given gapminder 2007: bars derived by mean, x is continent, y is life.” Each bar is one continent’s average. Unlike bin, which writes y itself, mean needs a column to average, and y(life) names it.

3.7 Five countries across the decades

Plots four to six show only 2007. A question about change needs many years, so the next plot uses another table.

How has life expectancy changed since 1952, and did five Asian countries change at the same rate? gapminder_asia holds one row per country and year, so each country appears twelve times, once every five years.

gapminder_asia: first 5 of 60 rows
country continent year life population gdp
China Asia 1952 44.00000 556263527 400.4486
China Asia 1957 50.54896 637408000 575.9870
China Asia 1962 44.50136 665770000 487.6740
China Asia 1967 58.38112 754550000 612.7057
China Asia 1972 63.11888 862030000 676.9001
data(gapminder_asia) + line + x(year) + y(life) + color(country)
data(gapminder_asia) + line + x(col.year) + y(col.life) + color(col.country)
data(gapminder_asia) + line + x(:year) + y(:life) + color(:country)
plot(data(gapminder_asia), line, x(col.year), y(col.life),
  color(col.country))
1960 1980 2000 40 50 60 70 80 Life Year Country China India Indonesia Japan Korea, Rep.

“Given gapminder Asia: lines, x is year, y is life, color by country.” A categorical color first splits the rows into one group per category (here, one line per country), then colors them. One channel does two things, and you write it once.

3.8 Three species on one axis

Plot three showed two peaks in petal length, and the table has three species. How do three species make two peaks?

data(iris_flowers) + bar * bin + x(petal_length) + color(species)
data(iris_flowers) + bar * bin + x(col.petal_length) + color(col.species)
data(iris_flowers) + bar * bin + x(:petal_length) + color(:species)
plot(data(iris_flowers), layer(bar, bin), x(col.petal_length),
  color(col.species))
2 4 6 0 10 20 30 40 Count Petal Length Species setosa versicolor virginica

“Given the iris flowers: bars derived by bin, x is petal length, color by species.” The left peak is setosa alone. The right peak is versicolor and virginica together, because their petal lengths overlap. All three histograms use the same bin edges, and each species has bars only in the bins its own values fall into. Each fill is translucent inside an opaque outline, so every histogram stays visible. color splits the rows here into one histogram per species, by the same rule as in plot seven.

3.9 One panel per continent

Richer countries live longer across the world as a whole, as the first chapter showed. Is that also true inside each continent?

data(gapminder_2007) + point + x(gdp, scale = "log") + y(life) | facet(continent)
data(gapminder_2007) + point + x(col.gdp, scale = "log") + y(col.life) | facet(col.continent)
data(gapminder_2007) + point + x(:gdp, scale = "log") + y(:life) |
  facet(:continent)
plot(data(gapminder_2007), point, x(col.gdp, { scale: "log" }),
  y(col.life), across(col.continent))
1K 10K 40 50 60 70 80 1K 10K 1K 10K 1K 10K 1K 10K Asia Europe Africa Americas Oceania Life Gdp

“Given gapminder 2007: points, x is gdp on a log scale, y is life, split into panel columns by continent.” Inside every continent except Oceania, which has only two countries here, life expectancy also rises with income. The rise is clearest in Europe and Asia and least clear in Africa, where the points are most scattered. The | operator splits the plot into panels side by side, one panel per category. All the panels share one pair of scales, so they can be compared; free = TRUE on a position fits that axis to each panel instead (Faceting). As in the first chapter, scale = "log" spreads out the poorer countries, which would otherwise be pressed together at the left edge.

3.10 Three measurements on three axes

Petal length alone left two species overlapping in plot eight. Two more measurements, sepal length and sepal width, might separate them, if all three measurements can be seen at once.

data(iris_flowers) + point +
  x(sepal_length) + y(sepal_width) + z(petal_length) +
  color(species)
(data(iris_flowers) + point +
  x(col.sepal_length) + y(col.sepal_width) + z(col.petal_length) +
  color(col.species))
data(iris_flowers) + point + x(:sepal_length) + y(:sepal_width) +
  z(:petal_length) + color(:species)
plot(data(iris_flowers), point, x(col.sepal_length), y(col.sepal_width),
  z(col.petal_length), color(col.species))
8 7 6 5 4 3 2 6 4 2 Sepal Length Sepal Width Petal Length Species setosa versicolor virginica

“Given the iris flowers: points, x is sepal length, y is sepal width, z is petal length, color by species.” Drawing in three dimensions needs no other package and no other mark. z is one more position channel, and the same sentence without z(petal_length) would draw a flat scatter. In the web edition the cube turns with a drag: drag right and the side facing you moves right, drag down and it tips down to show you the top. Every angle hides some points and shows others, so turn the cube more than once.

3.11 What you just did

Those ten plots used thirteen words: data, bar, point, line, bin, density, mean, x, y, z, color, facet, and the scale log. Every plot reads in the same order: data, mark, positions, then any refinements. A transform joined the mark and a facet came last, exactly where the first chapter put them. The same color split the bars and lines, and colored the points. The same * attached bin, mean and density, which derived counts, means and densities. Each word meant the same thing in every plot that used it.

3.12 What comes next

Every sentence here was already written, so nothing asked you to choose a mark. Writing practice reverses that: it starts from a question and asks you to write the sentence.