Dataslope logoDataslope

A Complete Workflow

A realistic end-to-end ggplot2 session — from a question, through exploratory plots, to a polished final figure — using the grammar at every step.

Let us put everything together the way you will actually use it: start with a question, explore quickly, then refine one chart into something worth sharing. Throughout, notice how the grammar guides every decision.

The question

How does engine displacement relate to highway fuel efficiency, and does that relationship depend on the type of car?

We have two continuous variables (displ, hwy) and a candidate grouping variable (class or drv). The grammar already tells us: two continuous variables → points; a group → color or facets.

Stage 1: a fast exploratory plot

Exploration values speed over polish. The minimal data + mapping + geom gets us looking immediately:

Code Block
R 4.6.0

There is a clear negative relationship. Good — the question is worth pursuing. Next: does it depend on car type?

Stage 2: bring in the grouping variable

Try color first, since it keeps everything in one panel:

Code Block
R 4.6.0

Interesting: front-wheel-drive cars (f) sit higher (more efficient). But the three colored clouds overlap. When color gets crowded, the grammar offers facets as the next move.

Stage 3: facet to separate the groups

Code Block
R 4.6.0

Now each drivetrain's trend is unmistakable, on shared axes so the panels are comparable. The exploratory phase has answered the question. Time to make it presentable.

The exploration-to-polish pipeline

The first three stages are exploration — bare and quick. Only now, at refinement, do we spend effort on scales, labels, and theme.

Stage 4: refine into a final figure

Add the communication layer — a meaningful title, plain-language axis labels, a deliberate color scale, and a clean theme:

Code Block
R 4.6.0

We dropped the legend (legend.position = "none") because the facet strips already name each drivetrain — a small judgment call the grammar made easy. The title now states the conclusion. This figure could go in a report unchanged.

Saving your work

Outside the browser, ggsave() writes the last plot (or a named plot object) to a file. The grammar's "a plot is a value" nature means you can pass the object directly:

p <- ggplot(mpg, aes(displ, hwy)) + geom_point()
ggsave("engine-efficiency.png", plot = p, width = 8, height = 5, dpi = 300)

The rhythm to internalize

Explore rough, refine once. Most of your plots will never leave the exploratory stage — they exist to answer a question for you. Spend polish effort only on the few that need to communicate to others. The grammar supports both: the same components, dialed from quick to publication-ready.

QuestionSelect one

In an exploratory data analysis, why start with a bare geom_point() (no titles, colors, or theme)?

Because adding color before a theme causes errors.

Because exploratory plots cannot have titles.

Because exploration prioritizes speed of insight — a minimal data + mapping + geom answers "is there anything here?" before any effort goes into polish.

Because geom_point is the only geom allowed during exploration.

QuestionSelect one

During refinement, the final figure sets legend.position = "none". Why is dropping the legend reasonable here?

Legends always clutter plots and should be removed.

The color mapping was deleted, so no legend is needed.

The plot is faceted by drivetrain, so each panel's strip label already identifies the group the legend would describe.

Themes cannot display legends.

Key takeaways

  • Let the grammar guide choices: variable count and type suggest the geom; crowded color suggests facets.
  • Work in stages — explore (minimal) → iterate → refine → share — and spend polish effort late, only on charts that must communicate.
  • Refinement is adding the scale, labels, and theme components on top of an already-correct exploratory plot.
  • A ggplot is a value: store it, grow it, and ggsave() it.

On this page