| 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 |
3 Reading practice
Can you tell what a plot shows before you see it? You have the vocabulary; now read with it. Ten plots follow, each a little more composed than the last. For each one: read the code aloud before looking at the picture, then check the picture against what you said. The reading is given under each plot, but it works better if you get there first.
3.1 Golds by country
medals holds one row per country, with a count of each medal won:
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))“Given the medals: bars, x is country, y is gold.” A bar measures an amount from zero, so the categories sit on x and the number rides on y. No transform anywhere: bar draws the numbers exactly as they arrive in the table.
3.2 The same bars, lying down
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))“Bars, x is gold, y is country.” Swap which axis carries the category and the bars lie down. There is no “horizontal bar” atom and no flip switch: orientation is read off the bindings, because the sentence already says everything.
3.3 One measurement’s shape
iris_flowers holds one row per flower: four measurements, and the species the flower belongs to.
| 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))“Bars derived by bin: x is petal length.” The * derives: bin cuts the axis into intervals and counts rows into them, and bar draws the counts. You did not bind y; bin invents the count, and the axis says so. Note the two humps; hold that thought for plot eight.
3.4 The same question, smoothly
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))“A line derived by density: x is life.” Same question as the histogram (how is this measurement distributed?), different derivation. Swap one atom, get the smooth estimate instead of the binned one.
3.5 Every country, one dot per continent
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))“Points, x is continent, y is life.” A categorical x gives each category a slot and stacks the points above it. That is the rule that placed bars on country slots in plot one, working here on a different mark. A plot shaped like this one has a name: the strip plot.
3.6 The typical value per continent
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))“Bars derived by mean: x is continent, y is life.” The strip plot above showed every country; * mean collapses each continent to its average. Here y(life) names the column the mean reads: a transform that reads a column makes you say which one.
3.7 Five countries across the decades
gapminder_asia holds one row per country and year, so each country appears many times.
| 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))“Given gapminder Asia: lines, x is year, y is life, color by country.” On a line, a categorical color first splits the rows into one line per category, then colors them. One channel, two duties, stated once.
3.8 Three species on one axis
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))“Bars derived by bin: x is petal length, color by species.” The two humps from plot three come apart. There is now one histogram per species. All three share the same bin edges and are drawn in place. Translucent fills sit under solid outlines, so nothing hides behind anything. The channel that split the lines in plot seven splits the bins here: same word, same rule.
3.9 One panel per 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))“Points, x is gdp on a log scale, y is life, split into panel columns by continent.” The | operator multiplies the plot across panels, one panel per category. All the panels share one pair of scales, so they can be compared.
3.10 Three measurements on three axes
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))“Points: x is sepal length, y is sepal width, z is petal length, color by species.” The third dimension is not a different package, and not a different mark. It is one more position channel, and the sentence grew by one word.
3.11 What you just did
Ten plots, and roughly a dozen distinct words. Every one read left to right as data, mark, positions, refinements. Nothing you learned for one plot had to be unlearned for the next. The same color split bars, lines and points. The same * derived counts, means and densities. Now you write.