Search code examples
rggplot2charts

Place geom_point() in the middle of dodged bars


I'm trying to draw points using geom_point() right in the middle of the two dodged bars created by geom_col().

These bars are dodged however and need to be to the right of the group label, that's why I'm using just = 0 in geom_col(). Moreover, I want to use position_dodge2() so there is no padding between the bars. I know this can be done with position_dodge() (see here), but that approach does not enable the dodged bars to be to the right of the ticks.

How do I provide geom_point() with the x-axis position in the middle of those bars that position_dodge2() uses?

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(ggplot2)

penguins_df <- tibble::tibble(
  island = factor(rep(c("Biscoe", "Dream", "Torgersen"), each = 3L)),
  name = rep(c("bill_length_mm", "bill_depth_mm", "flipper_length_mm"), 3),
  value = c(
    45.25748502994012, 15.874850299401198, 209.70658682634732, 44.16774193548387,
    18.344354838709677, 193.07258064516128, 38.950980392156865,
    18.429411764705883, 191.19607843137254
  ),
)


p <- ggplot(
  data = penguins_df,
  aes(
    x = island,
    y = value,
    group = name,
    fill = name,
    color = name
  )
) +
  geom_col(
    data = ~ filter(.x, name != "flipper_length_mm"),
    # Place columns to right of date breaks
    just = 0,
    position = position_dodge2(padding = 0)
  )

p +
  geom_point(
    data = ~ filter(.x, name == "flipper_length_mm"),
    position = position_dodge2()
  )
#> Warning: Width not defined. Set with `position_dodge2(width = ...)`

Created on 2024-05-22 with reprex v2.1.0


Solution

  • One way to do this is to adjust the x aesthetic in your final term...

    p +
      geom_point(
        data = ~ filter(.x, name == "flipper_length_mm"),
        aes(x = as.numeric(island) + 0.45),  #0.45 works for default bar spacing
        position = position_dodge2()
      )
    

    enter image description here