1  A first plot

Do countries that earn more live longer?

That is a question about data: 142 countries, each with a GDP per capita and a life expectancy.

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

In gog you answer a question like that by saying what the data means, rather than by drawing anything:

data(gapminder_2007) + point + x(gdp) + y(life)
data(gapminder_2007) + point + x(col.gdp) + y(col.life)
data(gapminder_2007) + point + x(:gdp) + y(:life)
plot(data(gapminder_2007), point, x(col.gdp), y(col.life))
0K 10K 20K 30K 40K 50K 40 50 60 70 80 Life Gdp

Read it aloud: “Given gapminder 2007: points, x is gdp, y is life.”

That sentence is the entire program. You named a table, a mark, and two positions; the engine chose the axes, the ticks, the margins, and drew one point per row. There is no draw call to make, because a plot here is a specification (a sentence about the picture, not a claim about the data), and rendering it is the engine’s job, not yours.

1.1 The boxes under every plot

Look under the plot above. A row of small boxes sits there, and every plot in this book has them. The magnifiers look closer and wider. The frame returns you to the whole picture. The hand is a label rather than a button: it says that dragging moves the picture, once you have looked closer. The camera saves what you are looking at as a picture file, large enough for a slide or a journal figure. A box is dimmed when it can do nothing.

Not one of these boxes has a word in the grammar, and that is deliberate. A word belongs in the grammar only if it changes what the plot claims about the data. Looking closer changes nothing: the points, the axes and the numbers stay the ones the engine chose. To make the plot itself cover a narrower range, write it in the sentence as limits.

1.2 Three steps to run any example

Everything in this book runs on your own computer, and it takes three steps:

  1. Install. The command for your language is in Installing gog.
  2. Load it. library(gog) in R, from gog import * in Python, using GrammarOfGraphics in Julia, and an import from grammar-of-graphics in JavaScript.
  3. Read a table. book_table("gapminder_2007") fetches the one above. It comes with the package, and Reading a table shows it in all four languages.

Every example after this one works from those three steps, and the table each needs is named in the sentence itself.

1.3 Add a word, ask a richer question

Which continent is which? Say so, one more word in the sentence:

data(gapminder_2007) + point + x(gdp) + y(life) + color(continent)
data(gapminder_2007) + point + x(col.gdp) + y(col.life) + color(col.continent)
data(gapminder_2007) + point + x(:gdp) + y(:life) + color(:continent)
plot(data(gapminder_2007), point, x(col.gdp), y(col.life),
  color(col.continent))
0K 10K 20K 30K 40K 50K 40 50 60 70 80 Life Gdp Continent Asia Europe Africa Americas Oceania

“…and color by continent.” The color() channel maps a column to a visual property, and because a mapping poses a question (which continent is this dot?), the engine draws the legend that answers it. You never asked for a legend. A mapped column earns one; that is the rule.

1.4 An incomplete sentence is refused

What happens if you forget a position? An incomplete sentence is refused the way a half-syllable is unpronounceable, and the refusal tells you what is missing:

data(gapminder_2007) + point + x(gdp)
Error:
! gog: `point` needs `y()` but none is set. Add `y(<column>)` — a point cannot be drawn without it.
gog: nothing was rendered. Fix the above, or set GOG_STRICT=0 to draw anyway.

This is worth meeting on your first page, because it is half of what makes gog learnable. A binding is a channel with a column in it, like x(gdp). The engine never accepts one and silently drops it, and every no comes with a direction. The errors are teachers here; the writing practice chapter collects the ones you will meet first.

1.5 Refine, don’t rebuild

The income axis is crowded on the left: most of the world earns far less than the richest countries. A logarithmic view is a property of how x is read, so it is written on the binding, and nothing else changes:

data(gapminder_2007) + point + x(gdp, scale = "log") + y(life) +
  color(continent) +
  title("The health and wealth of nations, 2007")
(data(gapminder_2007) + point + x(col.gdp, scale = "log") + y(col.life) +
  color(col.continent) +
  title("The health and wealth of nations, 2007"))
data(gapminder_2007) + point + x(:gdp, scale = "log") + y(:life) +
  color(:continent) + title("The health and wealth of nations, 2007")
plot(data(gapminder_2007), point, x(col.gdp, { scale: "log" }),
  y(col.life), color(col.continent),
  title("The health and wealth of nations, 2007"))
1K 10K 40 50 60 70 80 The health and wealth of nations, 2007 Life Gdp Continent Asia Europe Africa Americas Oceania

“Given gapminder 2007: points, x is gdp on a log scale, y is life, color by continent, titled.” Four refinements in, the sentence still reads left to right, and the first three words you learned are still doing the work.

1.6 The shape of every sentence

Every plot in this book, through the 3-D scenes at the end, is this same shape:

data(table) + mark + positions + refinements

A table bound once, so columns are bare names. A mark, the visible form. Positions, where the marks stand. Then any number of optional refinements: channels like color(), and labels like title().

Two words describe this, and the book uses both. A column is bound to a channel, and the binding is where a scale gets written. The same act is called mapping when the point is that a channel received a column rather than a fixed value. The difference shows on the page: a mapped column earns a legend, and a value you merely set earns none. A table is bound too, by data(), which is the Bind-Once law: name it once, and its columns stay bare names.

Two more parts join with an operator of their own. A transform attaches to its mark with *, which is how the preface’s bar * bin made a histogram. A facet splits the finished plot into panels with | or /. A scale is not a separate part at all: it is written on the position it belongs to, the way x(gdp, scale = "log") was written above. So the shape in full is:

data(table) + mark * transform + positions + refinements | facet(column)

The transform and the facet are optional, and so are the refinements. Delete every one of them and a legal plot remains. What cannot go is the table, the mark, and the positions that mark needs. That is the sentence you wrote at the top of this chapter.

Written grammar works the same way, which is why this one is called a grammar at all. “Birds sing” is already a complete sentence in English. “The small birds sing loudly in the morning” says much more, and every word added to it can be taken out again. Remove the verb instead and there is no sentence left to refine. A plot is not a different kind of object. Some parts carry it and the rest refine it. That division is the same in every plot in this book, so you learn it one time.

The next chapter lays out the whole vocabulary on one page, and it is shorter than you expect.