Adjusting geom_linerange with position_dodge in ggplot2
11:29 22 Feb 2026

I'm trying to plot lines just beneath a series of probability distributions using ggplot2. The data are held in two different data frames where a common ID column determines their position on the y-axis. I've used geom_ridgeline for the probability distributions and geom_linerange for the lines. The common ID's across the two data frames leads to the correct relative positions of the geoms on the y-axis, but using position_dodgde() with geom_linerange does not change the position of the lines:

library(ggplot2)
library(ggridges) # for geom_ridgeline

# Some mock data for the geom_ridgeline
df1 <- data.frame(date = c(-8274.5, -8269.5, -8264.5, -8259.5, -8254.5, -8249.5,
                           -8244.5, -8239.5, -8234.5, -8229.5, -8004.5,-7999.5,
                           -7994.5, -7989.5, -7984.5, -7979.5, -7974.5, -7969.5,
                           -7964.5, -7959.5),
                  probabilities = c(0.2310192, 0.2706921, 0.2493948, 0.2189172,
                                    0.1847136, 0.1559756, 0.1559756, 0.1863110,
                                    0.2409440, 0.3453804, 0.2310192, 0.2706921,
                                    0.2493948, 0.2189172, 0.1847136, 0.1559756,
                                    0.1559756, 0.1863110,
                                    0.2409440, 0.3453804),
                  id = factor(c(rep("First", 10), rep("Second", 10))))

# Corresponding mock data for the geom_linerange
df2 <- data.frame(start = c(-8269.5, -8244.5, -7999.5),
                  end = c(-8254.5, -8229.5, -7964.5),
                  id = factor(c("First", "First", "Second")))

# Call to plot
ggplot() +
  ggridges::geom_ridgeline(data = df1, 
                           aes(x = date,y = id, height = probabilities)) +
  geom_linerange(data = df2, 
                 aes(xmin = start, xmax = end, y = id, group = id),
                 col = "red", position = position_dodge(width = 1))

A ggplot with geom_ridgelines and geom_lineranges overlapping on the y-axis, even though I'm using position_dodge() to try to move the geom_linerange beneath the geom_ridgeline.

To be clear, I'd like there to be a slight gap between the position of the ridgelines and the lineranges. It appears position_dodge() does not have any effect when plotting only the geom_lineranges either:

ggplot() +
  geom_linerange(data = df2, 
                 aes(xmin = start, xmax = end, y = id, group = id),
                 col = "red", position = position_dodge(width = 1))

A version of the above plot only including the geom_linerange where position_dodge does not appear to have any effect either.

In previous questions like this one the issue appears to have been the necessity of also setting the group in aes() using a factor variable, but as can be seen above this does not solve my issue.

r ggplot2