ggplot2 geom_step() in R: Step Function Lines
The geom_step() function in ggplot2 draws connected lines that step rather than smoothly slope between points. It is the right choice for piecewise-constant data like cumulative event plots or empirical CDFs.
ggplot(df, aes(x, y)) + geom_step() ggplot(df, aes(x, y)) + geom_step(direction = "vh") # vertical-then-horizontal ggplot(df, aes(x, y)) + geom_step(direction = "hv") # horizontal-then-vertical (default) geom_line() # smooth/diagonal connections stat_ecdf() # cumulative distribution
Need explanation? Read on for examples and pitfalls.
What geom_step() does in one sentence
geom_step() connects points with HORIZONTAL and VERTICAL segments instead of diagonal ones, producing a stair-step appearance. Useful for piecewise-constant data.
Syntax
geom_step(direction = "hv", ...). direction is "hv" (default) or "vh".
Five common patterns
1. Cumulative event count
2. Direction "vh"
3. Empirical CDF
4. Compare hv vs vh
5. Multiple groups
geom_step() vs geom_line() vs geom_path()
| Function | Connection | Best for |
|---|---|---|
geom_step() |
Step (hv or vh) | Piecewise-constant |
geom_line() |
Diagonal lines | Smooth trends |
geom_path() |
Same as geom_line but follows row order | Trajectories |
A practical workflow
Use geom_step for "value changes at discrete events" plots.
Each price persists until the next change. Steps faithfully show this.
Common pitfalls
Pitfall 1: confusing direction. Default "hv" extends the previous y until the next x; "vh" jumps to new y first then extends. Pick based on data semantics.
Pitfall 2: using on smooth data. Step shows discrete changes. For continuous trends, use geom_line.
geom_step connects points in DATA ROW ORDER. If your data isn't sorted by x, the steps will be jumbled. Always arrange(x) first.Try it yourself
Try it: Plot a cumulative count of mtcars rows ordered by mpg using geom_step. Save to ex_plot.
Click to reveal solution
Explanation: Arrange by mpg, compute cumulative rank, plot as steps.
Related ggplot2 functions
After mastering geom_step, look at:
geom_line(): smooth connectionsgeom_path(): row-order linestat_ecdf(): empirical CDF (built on step)geom_segment(): explicit segment drawingscale_x_datetime(): time-axis scaling
FAQ
What does geom_step do in ggplot2?
geom_step() connects points with horizontal and vertical line segments, producing a stair-step appearance. Used for piecewise-constant data.
What is the difference between geom_step and geom_line?
geom_step uses right-angled segments (hv or vh). geom_line uses diagonal segments. Pick based on whether your data is piecewise-constant (step) or continuous (line).
What does direction "hv" mean?
Horizontal-first then vertical: extend previous y until next x, then jump to new y. Default. "vh" reverses.
Can I use geom_step for ECDF?
Yes, indirectly: stat_ecdf() is built on geom_step and is the standard ECDF function.
Does geom_step require sorted data?
Yes. It connects points in row order; unsorted data produces jumbled steps. arrange() first.