34  Selection

Which of these points are the rich countries, and where do they sit? A scatter with 142 dots answers slowly. Add one word and the reader can draw a box around any group and see the rest step back:

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

“Given gapminder 2007: points, x is gdp, y is life, color by continent, and let the reader select.”

On a page that can run the engine, drag across that plot. On paper it is the scatter itself, because nothing is selected until someone selects it.

Bare brush means the positions this plot binds, so here it is a region over gdp and life together. It says the plot is explorable without deciding in advance what is worth exploring.

Every country is still drawn while you drag. The ones inside your box keep their color and the rest are pushed back far enough to read as a background, so the group is read against what it was taken from. Remove the other rows and the plot no longer shows you that the rich countries are the top right corner of something.

34.1 Saying where the selection opens

Name a column and the brush is a bound on that column alone, which is how you point at something rather than let a reader look for it:

data(gapminder_2007) + point + x(gdp) + y(life) + color(continent) +
  theme(width = 620) + brush(gdp, at = c(20000, 60000))
(data(gapminder_2007) + point + x(col.gdp) + y(col.life) + color(col.continent) +
  theme(width = 620) + brush(col.gdp, at = [20000, 60000]))
data(gapminder_2007) + point + x(:gdp) + y(:life) + color(:continent) +
  theme(width = 620) + brush(:gdp, at = [20000, 60000])
plot(data(gapminder_2007), point, x(col.gdp), y(col.life),
  color(col.continent), theme({ width: 620 }),
  brush(col.gdp, { at: [20000, 60000] }))
0K 10K 20K 30K 40K 50K 40 50 60 70 80 Life Gdp Continent Asia Europe Africa Americas Oceania

The thirty or so countries above 20,000 dollars are lit, and you can see at once that they sit almost entirely above 75 years. That is closer to an annotation than to a tool: the sentence has done the selecting, and a reader can still drag to move the bound.

The two forms answer different questions, and the difference is who chooses. brush hands the choice to the reader. brush(gdp, at = ...) makes it in the sentence, and prints.

34.2 Highlighting, never removing rows

This is the one rule to learn, and it separates brush from an atom you already know. limits also takes a range in a column’s own units. It does something different with it.

limits runs before the statistics. It removes rows, and the transform then sees the survivors as if they were the whole data. brush runs after the picture is composed. It removes nothing and recomputes nothing.

One range, one mark, two outcomes:

data(gapminder_2007) + point + x(gdp, limits = c(20000, 60000)) + y(life) +
  theme(width = 620, height = 300) + title("limits: 114 countries gone")
(data(gapminder_2007) + point + x(col.gdp, limits = [20000, 60000]) + y(col.life) +
  theme(width = 620, height = 300) + title("limits: 114 countries gone"))
data(gapminder_2007) + point + x(:gdp, limits = [20000, 60000]) +
  y(:life) + theme(width = 620, height = 300) +
  title("limits: 114 countries gone")
plot(data(gapminder_2007), point, x(col.gdp, { limits: [20000, 60000] }),
  y(col.life), theme({ width: 620, height: 300 }),
  title("limits: 114 countries gone"))
20K 30K 40K 50K 60K 74 76 78 80 82 limits: 114 countries gone Life Gdp
data(gapminder_2007) + point + x(gdp) + y(life) +
  theme(width = 620, height = 300) + brush(gdp, at = c(20000, 60000)) +
  title("brush: all 142 still here")
(data(gapminder_2007) + point + x(col.gdp) + y(col.life) +
  theme(width = 620, height = 300) + brush(col.gdp, at = [20000, 60000]) +
  title("brush: all 142 still here"))
data(gapminder_2007) + point + x(:gdp) + y(:life) +
  theme(width = 620, height = 300) + brush(:gdp, at = [20000, 60000]) +
  title("brush: all 142 still here")
plot(data(gapminder_2007), point, x(col.gdp), y(col.life),
  theme({ width: 620, height: 300 }),
  brush(col.gdp, { at: [20000, 60000] }),
  title("brush: all 142 still here"))
0K 10K 20K 30K 40K 50K 40 50 60 70 80 brush: all 142 still here Life Gdp

The first plot is a different plot. Its axis runs from 20,000 to 60,000, only the countries inside that range are drawn, and both axes were fitted to the ones that survived. Look at its y axis: it starts near 70, because no short-lived country is left to stretch it downward. gog counts the countries it removed aloud rather than dropping them quietly.

The second is the whole world, with a group of it standing out. Its axes are the axes of all 142 countries, so the selection sits where it always sat. Stacked rather than side by side on purpose: the two share nothing, and setting them next to each other invites a reader to compare positions that were fitted to different data.

Which of the two you want is a real question and the grammar keeps both sayable. Ask how does this subgroup look on its own and you want limits. Ask where does this subgroup sit inside the whole and you want brush.

34.3 Two bounds make a rectangle

One brush is one column. Write two, and a row has to satisfy both:

data(gapminder_2007) + point + x(gdp) + y(life) + color(continent) +
  theme(width = 620) + brush(gdp, at = c(20000, 60000)) + brush(life, at = c(78, 85))
(data(gapminder_2007) + point + x(col.gdp) + y(col.life) + color(col.continent) +
  theme(width = 620) + brush(col.gdp, at = [20000, 60000]) + brush(col.life, at = [78, 85]))
data(gapminder_2007) + point + x(:gdp) + y(:life) + color(:continent) +
  theme(width = 620) + brush(:gdp, at = [20000, 60000]) +
  brush(:life, at = [78, 85])
plot(data(gapminder_2007), point, x(col.gdp), y(col.life),
  color(col.continent), theme({ width: 620 }),
  brush(col.gdp, { at: [20000, 60000] }),
  brush(col.life, { at: [78, 85] }))
0K 10K 20K 30K 40K 50K 40 50 60 70 80 Life Gdp Continent Asia Europe Africa Americas Oceania

The rich countries that also live longest. Two of the countries that survived the first bound do not survive this one, and you can see exactly which two, because they are still on the page.

Writing it as two atoms rather than one with two arguments follows the rest of the grammar. A position is one column at a time, and so is a bound.

34.4 A column of categories selects slots

at is where the selection opens. What you give it says which kind of column you meant, in the same way a column decides whether color hands out a ramp or a palette. Numbers are a range. Names are a set of slots:

data(gapminder_2007) + point + x(continent) + y(life) + color(continent) +
  theme(width = 620) + brush(continent, at = c("Europe", "Oceania"))
(data(gapminder_2007) + point + x(col.continent) + y(col.life) + color(col.continent) +
  theme(width = 620) + brush(col.continent, at = ["Europe", "Oceania"]))
data(gapminder_2007) + point + x(:continent) + y(:life) +
  color(:continent) + theme(width = 620) +
  brush(:continent, at = ["Europe", "Oceania"])
plot(data(gapminder_2007), point, x(col.continent), y(col.life),
  color(col.continent), theme({ width: 620 }),
  brush(col.continent, { at: ["Europe", "Oceania"] }))
Asia Europe Africa Americas Oceania 40 50 60 70 80 Life Continent Continent Asia Europe Africa Americas Oceania

One word, two readings, decided by the column rather than by a second atom. Drag across the slots and the selection follows them, whole slots at a time, because a category has no half.

The column is on the x axis here and that is not decoration. A drag can only reach a column the panel places. Written over the scatter this chapter opened with, where continent is a color and nothing else, brush(continent, at = ...) is still a legal sentence and still dims the right countries, but there is nowhere to drag, because no axis is measuring continents. The sentence has said everything, and the mouse has nothing left to say.

Which axis places it does not matter. Here is the same sentence with x and y exchanged:

data(gapminder_2007) + point + x(life) + y(continent) + color(continent) +
  theme(width = 620, height = 320) + brush(continent, at = c("Europe", "Oceania"))
(data(gapminder_2007) + point + x(col.life) + y(col.continent) + color(col.continent) +
  theme(width = 620, height = 320) + brush(col.continent, at = ["Europe", "Oceania"]))
data(gapminder_2007) + point + x(:life) + y(:continent) +
  color(:continent) + theme(width = 620, height = 320) +
  brush(:continent, at = ["Europe", "Oceania"])
plot(data(gapminder_2007), point, x(col.life), y(col.continent),
  color(col.continent), theme({ width: 620, height: 320 }),
  brush(col.continent, { at: ["Europe", "Oceania"] }))
40 50 60 70 80 Oceania Americas Africa Europe Asia Continent Life Continent Asia Europe Africa Americas Oceania

The slots stack up the side now, and the same two continents are lit. Drag on it and the band lies across the panel instead of standing in it, whole slots at a time as before. The bound never mentions an axis. It names a column, so turning the plot moves the drag and leaves the sentence alone.

34.5 Two views, one selection

This is the use a brush was invented for, and everything above it has been the setup. Selecting inside one plot tells you little you could not already see. The question worth asking is where does this group sit in a different picture, and that needs a second picture:

(data(gapminder_2007) + point + x(gdp) + y(life) +
   brush(gdp, at = c(20000, 60000)) + theme(height = 230)) /
  (data(gapminder_2007) + point + x(gdp) + y(population, scale = "log") +
     brush(gdp, at = c(20000, 60000)) + theme(height = 200))
((data(gapminder_2007) + point + x(col.gdp) + y(col.life) +
   brush(col.gdp, at = [20000, 60000]) + theme(height = 230)) /
  (data(gapminder_2007) + point + x(col.gdp) + y(col.population, scale = "log") +
     brush(col.gdp, at = [20000, 60000]) + theme(height = 200)))
(data(gapminder_2007) + point + x(:gdp) + y(:life) +
  brush(:gdp, at = [20000, 60000]) + theme(height = 230)) /
  (data(gapminder_2007) + point + x(:gdp) +
  y(:population, scale = "log") + brush(:gdp, at = [20000, 60000]) +
  theme(height = 200))
below(plot(data(gapminder_2007), point, x(col.gdp), y(col.life),
  brush(col.gdp, { at: [20000, 60000] }), theme({ height: 230 })),
  plot(data(gapminder_2007), point, x(col.gdp),
  y(col.population, { scale: "log" }),
  brush(col.gdp, { at: [20000, 60000] }), theme({ height: 200 })))
40 50 60 70 80 Life 0K 20K 40K 1M 10M 100M 1B Population Gdp

Two plots, one page, and one bound lighting the same countries in both. Drag in either and the other follows. The rich countries live long, which the top plot says; they are also mostly small, which only the bottom one says, and neither plot could have told you both.

Nothing was added to the grammar to link them. Look at what the two sentences share: the column gdp, named on x in each. A bound is a fact about a column’s values rather than about a panel, so two plots that read that column are already answering the same question. There is no name to declare, no identifier to match up, and no third atom joining them.

That falls out of composition’s one rule, arriving somewhere new. Two composed plots naming the same column on the same axis share that axis, which is why these two are the same width and the gdp numbers are written once. The selection travels the same road for the same reason.

34.6 Which one is that?

The other thing people want from a selection is a name. Layer text over the points and the brush decides which labels are legible:

data(gapminder_2007) + point + x(gdp) + y(life) +
  text + label(country) + style(size = 7) +
  brush(gdp, at = c(30000, 60000)) + theme(width = 620)
(data(gapminder_2007) + point + x(col.gdp) + y(col.life) +
  text + label(col.country) + style(size = 7) +
  brush(col.gdp, at = [30000, 60000]) + theme(width = 620))
data(gapminder_2007) + point + x(:gdp) + y(:life) + text +
  label(:country) + style(size = 7) + brush(:gdp, at = [30000, 60000]) +
  theme(width = 620)
plot(data(gapminder_2007), point, x(col.gdp), y(col.life), text,
  label(col.country), style({ size: 7 }),
  brush(col.gdp, { at: [30000, 60000] }), theme({ width: 620 }))
Afghanistan Albania Algeria Angola Argentina Bahrain Bangladesh Benin Bolivia Bosnia and Herzegovina Botswana Brazil Bulgaria Burkina Faso Burundi Cambodia Cameroon Central African Republic Chad Chile China Colombia Comoros Congo, Dem. Rep. Congo, Rep. Costa Rica Cote d'Ivoire Croatia Cuba Czech Republic Djibouti Dominican Republic Ecuador Egypt El Salvador Equatorial Guinea Eritrea Ethiopia Gabon Gambia Ghana Greece Guatemala Guinea Guinea-Bissau Haiti Honduras Hungary India Indonesia Iran Iraq Israel Italy Jamaica Jordan Kenya Korea, Dem. Rep. Korea, Rep. Lebanon Lesotho Liberia Libya Madagascar Malawi Malaysia Mali Mauritania Mauritius Mexico Mongolia Montenegro Morocco Mozambique Myanmar Namibia Nepal New Zealand Nicaragua Niger Nigeria Oman Pakistan Panama Paraguay Peru Philippines Poland Portugal Puerto Rico Reunion Romania Rwanda Sao Tome and Principe Saudi Arabia Senegal Serbia Sierra Leone Slovak Republic Slovenia Somalia South Africa Spain Sri Lanka Sudan Swaziland Syria Taiwan Tanzania Thailand Togo Trinidad and Tobago Tunisia Turkey Uganda Uruguay Venezuela Vietnam West Bank and Gaza Yemen, Rep. Zambia Zimbabwe Australia Austria Belgium Canada Denmark Finland France Germany Hong Kong, China Iceland Ireland Japan Kuwait Netherlands Norway Singapore Sweden Switzerland United Kingdom United States 0K 10K 20K 30K 40K 50K 40 50 60 70 80 Life Gdp

A hundred and forty-two labels is unreadable, and that is the point: the ones you did not select step back with their points, and about twenty names are left standing. Drag the bound and a different twenty are readable.

This works because text is one of the marks a brush reaches, on the same test as point: one row is one label. Nothing here is about selection and labels being designed together, because they were not.

34.7 What can be brushed

A selection picks out rows, so a mark can be brushed when one row is one shape: point, text, rule and zone.

A line is the other case. It draws one shape through many rows, so a row is a corner of the line rather than a thing of its own. Selecting half of a line would mean cutting it in two, and cutting a line in two already has a word:

data(gapminder_asia) + line + x(year) + y(life) + group(country) +
  brush(life, at = c(60, 80))
Error:
! gog: a `line` draws one shape through many rows, so there is no single row to select. Use `group()` to split it, or brush a mark that draws one shape per row: `point`, `text`, `rule` or `zone`.
gog: nothing was rendered. Fix the above, or set GOG_STRICT=0 to draw anyway.

The refusal names both ways forward. Split the line with group(), or brush a mark that draws one shape per row.

A summarized layer refuses for a different reason. A bar of bar * count stands for forty countries at once, so “twelve of these are selected” has no honest picture: dimming the whole bar would be wrong, and dimming part of it would invent a mark nobody asked for. gog says so instead of guessing:

data(gapminder_2007) + bar * count + x(continent) +
  brush(gdp, at = c(20000, 60000))
Error:
! gog: `bar * count` cannot be brushed, because `count` summarizes many rows into one and the engine cannot say which of them you selected. Brush the layer that draws the rows themselves, or drop the brush.
gog: nothing was rendered. Fix the above, or set GOG_STRICT=0 to draw anyway.

Beside a layer that can answer, neither of these is a refusal. The plot draws, and gog reports which layer it left whole:

data(gapminder_2007) + point + x(gdp) + y(life) +
  line * smooth +
  brush(gdp, at = c(20000, 60000))
(data(gapminder_2007) + point + x(col.gdp) + y(col.life) +
  line * smooth +
  brush(col.gdp, at = [20000, 60000]))
data(gapminder_2007) + point + x(:gdp) + y(:life) + line * smooth +
  brush(:gdp, at = [20000, 60000])
plot(data(gapminder_2007), point, x(col.gdp), y(col.life),
  layer(line, smooth), brush(col.gdp, { at: [20000, 60000] }))
gog: the `line` layer is drawn whole, because it draws one shape through many rows and there is no single row to select. The selection still reads on the rest of the plot.
0K 10K 20K 30K 40K 50K 40 50 60 70 80 Life Gdp

The points answer the selection and the trend line does not, so the line is drawn once, at full strength, through all 142 countries. That is the right answer: a trend fitted to the selection alone would be a different statistic, and the sentence did not ask for one.

A range that does not run upward selects nothing, so it is a mistake rather than an empty selection:

data(gapminder_2007) + point + x(gdp) + y(life) +
  brush(gdp, at = c(60000, 20000))
Error:
! gog: `brush(gdp, at = c(60000, 20000))` selects nothing, because the range does not run upward. Write the smaller number first.
gog: nothing was rendered. Fix the above, or set GOG_STRICT=0 to draw anyway.

34.8 Selecting while the plot plays

A frame is a subset of the rows, and a bound is a test on a column’s values, so the two compose and neither needed anything added for the other. The bound is tested again inside every frame:

data(gm_all) + point + x(gdp, scale = "log") + y(life) + color(continent) +
  theme(width = 620) + play(year) + brush(gdp, at = c(3000, 20000))
(data(gm_all) + point + x(col.gdp, scale = "log") + y(col.life) + color(col.continent) +
  theme(width = 620) + play(col.year) + brush(col.gdp, at = [3000, 20000]))
data(gm_all) + point + x(:gdp, scale = "log") + y(:life) +
  color(:continent) + theme(width = 620) + play(:year) +
  brush(:gdp, at = [3000, 20000])
plot(data(gm_all), point, x(col.gdp, { scale: "log" }), y(col.life),
  color(col.continent), theme({ width: 620 }), play(col.year),
  brush(col.gdp, { at: [3000, 20000] }))
1K 10K 100K 40 60 80 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 2002 2007 Life Gdp Continent Asia Europe Africa Americas Oceania

Watch countries cross into the selection and light up. The bound holds still at 3,000 to 20,000 dollars and the world moves through it: in 1952 the lit group is the middle-income countries of the day, and by 2007 many of them have left it through the top while others have arrived from below. Nothing pauses, and no frame is skipped. The same test simply gets a different answer in each one, which is what makes a brush a threshold you watch the world cross.

Choosing a bound the data actually crosses is worth a moment, and it is the one piece of judgment this atom asks of you. The two ends of a sequence are where an animation misleads. Count what a bound catches in each frame before you write it down: 3,000 to 20,000 dollars lights between 52 and 74 countries in every frame of this sequence, while 20,000 and up lights none at all in 1952 and 1957, one in 1962, and four by 1972. The second is a true picture and it reads as a broken plot, because a reader cannot tell nothing is selected here from this is not working. Drag the bound upward and you will watch it happen.

One column cannot do both jobs. Brushing the column the frames are cut on would select frames rather than rows inside one, and that is a scrub bar rather than a selection:

data(gm_all) + point + x(gdp) + y(life) + play(year) + brush(year, at = c(1980, 2007))
Error:
! gog: `year` is already the column `play()` cuts the frames on, so `brush(year)` would select frames rather than rows inside one. That is a scrub bar, which belongs to the viewer and not to the sentence. Brush a column the frames are not cut on.
gog: nothing was rendered. Fix the above, or set GOG_STRICT=0 to draw anyway.

A scrub bar belongs to the page a plot is shown on, not to the sentence that describes the plot. Play says why.

34.9 All three at once

The third position, the frames and the selection are three separate ideas, and none of them was taught about the others. So they compose:

data(gm_all) + point + x(gdp, scale = "log") + y(life) + z(population) +
  color(continent) + play(year) + brush(gdp, at = c(3000, 20000))
(data(gm_all) + point + x(col.gdp, scale = "log") + y(col.life) + z(col.population) +
  color(col.continent) + play(col.year) + brush(col.gdp, at = [3000, 20000]))
data(gm_all) + point + x(:gdp, scale = "log") + y(:life) +
  z(:population) + color(:continent) + play(:year) +
  brush(:gdp, at = [3000, 20000])
plot(data(gm_all), point, x(col.gdp, { scale: "log" }), y(col.life),
  z(col.population), color(col.continent), play(col.year),
  brush(col.gdp, { at: [3000, 20000] }))
100K 10K 1K 80 60 40 1000M 500M 0M Gdp Life Population 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 2002 2007 Continent Asia Europe Africa Americas Oceania

A cube of 142 countries, twelve moments, and one bound tested inside every one of them. Drag the plot to turn it and the selection turns with the cloud, because the bound picks rows and the angle picks a viewpoint, and neither asks the other anything.

There is one difference here, and it is worth knowing rather than working out. In the cube the drag already belongs to the camera, so the sentence has to name the bound: brush on its own would declare a region with no way to draw one. That is the same rule as everywhere else in this chapter, arriving from the other side. A drag means one thing at a time, and in the cube it means turn.

34.10 Moving the bound yourself

Every plot in this chapter after the first names where its selection opens. On a page that can run the engine, you can drag the panel to move the bound, and the plot redraws under your hand.

This changes nothing about the sentence, and it is the same arrangement the cube uses. space(turn =, tilt =) chooses the angle a plot opens at and the mouse takes you anywhere else; brush(gdp, at = ) chooses the bound a plot opens with and the mouse does the same. Drag to find a selection, then write it into the sentence.

On paper, and in the PDF edition, each plot shows the bound its sentence asked for. That is why naming it is worth doing even though a reader can move it. The printed figure shows the selection you chose, and a reader who can drag starts from it.

Written with no at at all, nothing is selected. The plot then draws exactly as it would with no brush in the sentence, which is the resting state a page shows before the first drag.

34.11 What the page adds

A brushed plot on a web page carries a line of controls under it. None of them are in the sentence, and that is the rule rather than an omission. They report a selection or change how you look at one. Neither changes what the plot claims about the data, so neither earns a word in the grammar. It is the same reason a plot in the cube has a line of controls and space() has no word for the mouse.

Reading left to right, the line looks like this:

Control What it does
drag: and its icons Says what dragging the plot will do, and switches it: a rectangle, a free shape, or moving the picture
17 of 142 selected How many rows the current bound catches
show rows Opens a table of those rows, and closes it again. A long selection arrives ten at a time, with and under the table
clear Puts the selection back to what the sentence asked for
+ Makes the picture smaller or larger
fit Returns to the whole picture

34.11.1 Selecting

Drag across the panel. A dotted box follows the pointer, and it shows exactly what is bound. On a plot with one brush the box spans the whole panel in the other direction, because that direction was not selected. On a plot with two, it is a rectangle. A box that narrowed an axis nobody bound would be claiming a range you did not choose.

Dragging in either direction gives the same bound, so you can start from any corner. A single click clears the selection, which is what a click on empty space does everywhere else.

34.11.2 Drawing around a group

A rectangle is what a sentence can say. Some groups are not rectangles. A cloud of points often has a shape: an arm reaching out to one side, a curve, a clump away from the rest. A box drawn around such a group includes points you did not mean.

The second icon beside drag: is the free shape. Choose it, then draw around the group with the pointer held down. The outline closes itself when you let go, and everything inside it is selected. The count and the row table read exactly as they do for a box, because a shape and a bound ask the same question: which rows do you mean.

Nothing about the sentence changes. You do not type a shape, and the printed page still shows the bound the sentence named. Drawing one is a way of looking, like turning a cube, rather than a claim about the data.

That is also why the grammar has no word for it. gog reserved lasso for this once and then gave the word up. A shape can only be written down as a long list of corners, and a specification is something you can write down and print. The act survives; the word does not.

Two limits are worth knowing. A free shape needs two axes that measure, so where one axis carries categories the drag stays a rectangle. A category has no half, and whole slots are what you wanted there anyway. And clear removes the shape instead of restoring it, because a shape has no resting form for a sentence to state.

34.11.3 Reading what you caught

The count is always there. show rows opens a table underneath, listing the columns the sentence maps rather than every column in the table, because twelve columns of a spreadsheet are not what you are looking at.

A long selection arrives ten rows at a time. The line under the table says which rows you are reading, as 11–20 of 40, and the two arrows beside it move you through the rest. Every row you selected is reachable, and none of them pushes the plot off the screen. A selection short enough to fit shows no arrows at all.

That table answers the question people usually reach for a click to ask. Draw a bound tight around one point and it names that point.

For a quick look without selecting anything, move the pointer over a mark and that row’s values appear beside it. Nothing is selected and nothing changes.

34.11.4 Looking closer

+ and magnify the picture and fit returns to the whole of it. Zooming in switches the drag to panning, because a reader who has just looked closer usually wants to move around inside it; fit hands the drag back to selecting. You can switch by hand at any time with the button on the left, and the pointer tells you which mode you are in: a crosshair to draw a box, an open hand to move the picture.

This is a view, so it recomputes nothing. The bars are the same bars and the ticks are the same ticks, drawn larger. Zoom far enough into a histogram and you will see the same bins, not finer ones. If you want the statistics re-run over a narrower range, that is limits, and it is the other operation this chapter opened with.

34.11.5 Two words, two things

clear acts on the selection and fit acts on the view. They are next to each other and they undo different things, so they are named for what they act on rather than both being called reset.

None of this exists on paper, and none of it is missing there. The PDF shows the bound the sentence named, which is why naming one is worth doing even where a reader can move it.