ggplot2 geom_path() in R: Connect Points in Data Order

The geom_path() function in ggplot2 connects points with line segments in DATA ROW ORDER (not sorted by x). It is the right tool for trajectory plots, paths, and any sequence where order matters.

⚡ Quick Answer
ggplot(df, aes(x, y)) + geom_path()
ggplot(df, aes(x, y, color = step)) + geom_path()
geom_line()                              # different: sorts by x first
geom_path(arrow = arrow())               # add arrow at end

Need explanation? Read on for examples and pitfalls.

📊 Is geom_path() the right tool?
START2D trajectory in time ordergeom_path()traditional line plot (sorted x)geom_line()step functiongeom_step()closed polygongeom_polygon()

What geom_path() does in one sentence

geom_path() connects points with line segments in the ORDER they appear in the data. Unlike geom_line (which sorts by x first), geom_path respects row order.

Syntax

geom_path(mapping = NULL, data = NULL, lineend = "butt", linejoin = "round", linemitre = 10, arrow = NULL, ...).

Run live
Run live, no install needed. Every R block on this page runs in your browser. Click Run, edit the code, re-run instantly. No setup.
RRandom walk trajectory
library(ggplot2) set.seed(1) df <- tibble( step = 1:50, x = cumsum(rnorm(50)), y = cumsum(rnorm(50)) ) ggplot(df, aes(x, y)) + geom_path()

  
Tip
Use geom_path for spatial trajectories, animation paths, and any data where the connection order matters. Use geom_line for traditional trends.

Five common patterns

1. Random walk

R2D trajectory
df <- tibble( step = 1:100, x = cumsum(rnorm(100)), y = cumsum(rnorm(100)) ) ggplot(df, aes(x, y)) + geom_path()

  

2. Color by step

RShow progression
ggplot(df, aes(x, y, color = step)) + geom_path()

  

3. With arrow

RMark direction
ggplot(df, aes(x, y)) + geom_path(arrow = arrow(length = unit(0.3, "cm")))

  

4. Multiple paths (groups)

RPer-group trajectories
ggplot(df, aes(x, y, group = trial, color = trial)) + geom_path()

  

5. Closed loop

RConnect last to first
df_closed <- bind_rows(df, df[1, ]) # repeat first row ggplot(df_closed, aes(x, y)) + geom_path()

  
Key Insight
geom_path is for SEQUENCED data where the order between points matters. geom_line sorts internally, so it's wrong for trajectories where the path crosses itself.

geom_path() vs geom_line() vs geom_step()

Function Order Best for
geom_path() Row order Trajectories, paths
geom_line() Sorted by x Traditional trends
geom_step() Row order with steps Piecewise-constant
geom_polygon() Closed loop Filled shapes

A practical workflow

Use geom_path for time-series with non-monotonic x.

RInteractive R
ggplot(market_data, aes(volatility, return, color = date)) + geom_path() + geom_point()

  

Plot return vs volatility over time; the PATH shows how each point connects chronologically.

Common pitfalls

Pitfall 1: confusing geom_path with geom_line. geom_path keeps row order; geom_line sorts. For trajectories with non-monotonic x, geom_line is WRONG.

Pitfall 2: forgetting to arrange data. geom_path follows row order. If you want chronological order, arrange by timestamp first.

Warning
geom_path() does NOT close the polygon. First and last points are not connected. To close, append the first row to the end before plotting.

Try it yourself

Try it: Plot a 2D random walk path with color showing step. Save to ex_plot.

RYour turn: random walk
set.seed(42) df <- tibble(step = 1:50, x = cumsum(rnorm(50)), y = cumsum(rnorm(50))) ex_plot <- df |> # your code here

  
Click to reveal solution
RSolution
ex_plot <- ggplot(df, aes(x, y, color = step)) + geom_path()

  

Explanation: geom_path connects points in row (= step) order; color gradient shows direction.

After mastering geom_path, look at:

  • geom_line(): sorted by x
  • geom_step(): piecewise-constant
  • geom_polygon(): closed shape
  • geom_segment(): explicit segments
  • arrow(): add direction markers

FAQ

What does geom_path do in ggplot2?

geom_path() connects points with line segments in DATA ROW ORDER. Unlike geom_line, it does not sort by x.

What is the difference between geom_path and geom_line?

geom_path keeps row order. geom_line sorts by x. For trajectories or non-monotonic x, geom_path is correct.

How do I add an arrow to geom_path?

Pass arrow = arrow(length = unit(0.3, "cm")): geom_path(arrow = arrow()). An arrowhead appears at the end.

Does geom_path close polygons?

No. First and last points are NOT connected. For closed loops, append the first row to the end of the data before plotting (or use geom_polygon).

Can I use geom_path for time-series?

Yes, especially when (x, y) are both varying and the chronological order matters. For x = time, y = value with monotonic time, geom_line is fine.