ggrepel positions

library(ggplot2)
library(ggrepel)
p <- ggplot(mtcars,
            aes(wt, mpg, label = rownames(mtcars), colour = factor(cyl))) +
  geom_point() +
  geom_text_repel(seed = 1)

# Not available at `ggplot_build()` - x/y pos is untransformed data values
identical(
  unlist(mtcars[, c("wt", "mpg")], use.names = FALSE),
  unlist(layer_data(p, 2L)[, c("x", "y")], use.names = FALSE)
)
[1] TRUE
# Not available at `ggplot_gtable()` - no labels materialized within layer
layer_grob(p, 2L)[[1]]$children
() 
# IS available at `grid.draw()`, upon evaluation of `ggrepel:::makeContent.textrepeltree()`
# - need some extra work to get the materialized grobs with `grid.force()` and `grid.get()`
library(grid)
plot(p)
grid.force()

x <- grid.ls()
layout
  background.1-13-16-1
    plot.background..rect.68
  panel.9-7-9-7
    panel-1.gTree.21
      grill.gTree.19
        panel.background..rect.10
        panel.grid.minor.y..polyline.12
        panel.grid.minor.x..polyline.14
        panel.grid.major.y..polyline.16
        panel.grid.major.x..polyline.18
      NULL
      geom_point.points.4
      geom_text_repel.textrepeltree.6
        segmentrepelgrob10
          segment
        segmentrepelgrob16
          segment
        segmentrepelgrob22
          segment
        segmentrepelgrob25
          segment
        segmentrepelgrob30
          segment
        textrepelgrob1
        textrepelgrob2
        textrepelgrob3
        textrepelgrob4
        textrepelgrob5
        textrepelgrob6
        textrepelgrob7
        textrepelgrob8
        textrepelgrob9
        textrepelgrob10
        textrepelgrob11
        textrepelgrob12
        textrepelgrob13
        textrepelgrob14
        textrepelgrob15
        textrepelgrob16
        textrepelgrob17
        textrepelgrob18
        textrepelgrob19
        textrepelgrob20
        textrepelgrob21
        textrepelgrob22
        textrepelgrob24
        textrepelgrob25
        textrepelgrob26
        textrepelgrob27
        textrepelgrob28
        textrepelgrob29
        textrepelgrob30
        textrepelgrob31
        textrepelgrob32
      NULL
      panel.border..zeroGrob.7
  spacer.10-8-10-8
    NULL
  spacer.10-6-10-6
    NULL
  spacer.8-8-8-8
    NULL
  spacer.8-6-8-6
    NULL
  axis-t.8-7-8-7
    NULL
  axis-l.9-6-9-6
    GRID.absoluteGrob.30
      NULL
      axis
        axis.1-3-1-3
          GRID.titleGrob.29
            GRID.text.28
        axis.1-6-1-6
          GRID.polyline.27
        axis.1-1-1-1
          NULL
  axis-r.9-8-9-8
    NULL
  axis-b.10-7-10-7
    GRID.absoluteGrob.26
      NULL
      axis
        axis.1-1-1-1
          GRID.polyline.22
        axis.4-1-4-1
          GRID.titleGrob.25
            GRID.text.23
        axis.6-1-6-1
          NULL
  xlab-t.7-7-7-7
    NULL
  xlab-b.11-7-11-7
    axis.title.x.bottom..titleGrob.34
      GRID.text.31
  ylab-l.9-5-9-5
    axis.title.y.left..titleGrob.37
      GRID.text.35
  ylab-r.9-9-9-9
    NULL
  guide-box-right.9-11-9-11
    guide-box
      legend.box.background.2-4-4-2
        NULL
      guides.3-3-3-3
        layout
          background.1-6-8-1
            legend.background.rect.39
          title.2-4-2-3
            guide.title.titleGrob.44
              GRID.text.42
          .3-3-3-3
            legend.key.rect.41
          geom_point.3-3-3-3
            GRID.points.54
          geom_text_repel.3-3-3-3
            GRID.titleGrob.57
              GRID.text.55
          .5-3-5-3
            legend.key.rect.41
          geom_point.5-3-5-3
            GRID.points.58
          geom_text_repel.5-3-5-3
            GRID.titleGrob.60
              GRID.text.59
          .7-3-7-3
            legend.key.rect.41
          geom_point.7-3-7-3
            GRID.points.61
          geom_text_repel.7-3-7-3
            GRID.titleGrob.63
              GRID.text.62
          label-1-2.3-4-3-4
            guide.label.titleGrob.47
              GRID.text.45
          label-3-2.5-4-5-4
            guide.label.titleGrob.50
              GRID.text.48
          label-5-2.7-4-7-4
            guide.label.titleGrob.53
              GRID.text.51
  guide-box-left.9-3-9-3
    NULL
  guide-box-bottom.13-7-13-7
    NULL
  guide-box-top.5-7-5-7
    NULL
  guide-box-inside.9-7-9-7
    NULL
  subtitle.4-7-4-7
    plot.subtitle..zeroGrob.65
  title.3-7-3-7
    plot.title..zeroGrob.64
  caption.14-7-14-7
    plot.caption..zeroGrob.66
repel_grob_nm <- grep(x = x$name, "textrepeltree", value = TRUE)
repel_grob_nm
[1] "geom_text_repel.textrepeltree.6"
repel_grob <- grid.get(repel_grob_nm)
# Drawn labels available for inspection from the `<forcedgrob>`
repel_grob$children
(forcedgrob[segmentrepelgrob10], forcedgrob[segmentrepelgrob16], forcedgrob[segmentrepelgrob22], forcedgrob[segmentrepelgrob25], forcedgrob[segmentrepelgrob30], text[textrepelgrob1], text[textrepelgrob2], text[textrepelgrob3], text[textrepelgrob4], text[textrepelgrob5], text[textrepelgrob6], text[textrepelgrob7], text[textrepelgrob8], text[textrepelgrob9], text[textrepelgrob10], text[textrepelgrob11], text[textrepelgrob12], text[textrepelgrob13], text[textrepelgrob14], text[textrepelgrob15], text[textrepelgrob16], text[textrepelgrob17], text[textrepelgrob18], text[textrepelgrob19], text[textrepelgrob20], text[textrepelgrob21], text[textrepelgrob22], text[textrepelgrob24], text[textrepelgrob25], text[textrepelgrob26], text[textrepelgrob27], text[textrepelgrob28], text[textrepelgrob29], text[textrepelgrob30], text[textrepelgrob31], text[textrepelgrob32]) 
# These hold the npc coordinate values
repel_grob$children$textrepelgrob15$x
[1] sum(0.873703844920667native, 0char, 0char)
# The ggrepel grob stores info from data after `ggplot_build()`, so you can
# cross-check that to recover what element corresponds to which row in data
is.data.frame(repel_grob$data)
[1] TRUE
# Example of recovery
repel_pos <- repel_grob$children |>
  Filter(x = _, \(g) grepl(x = g$name, "textrepelgrob")) |>
  lapply(\(g) sapply(g[c("x", "y")], convertUnit, "native", valueOnly = TRUE)) |>
  do.call(rbind, args = _) |>
  tibble::as_tibble(rownames = "textid")
repel_pos_data <- repel_grob$data[
  as.integer(gsub(x = repel_pos$textid, "textrepelgrob", "")), 
  c("label", "colour") # size, alpha, ...
]
repel_df <- cbind(repel_pos, repel_pos_data)
repel_df
            textid          x          y               label  colour
1   textrepelgrob1 0.25467785 0.42832634           Mazda RX4 #00BA38
2   textrepelgrob2 0.45243991 0.42828142       Mazda RX4 Wag #00BA38
3   textrepelgrob3 0.20577200 0.55237465          Datsun 710 #F8766D
4   textrepelgrob4 0.52471292 0.49826447      Hornet 4 Drive #00BA38
5   textrepelgrob5 0.36893839 0.37799376   Hornet Sportabout #619CFF
6   textrepelgrob6 0.55258782 0.35851726             Valiant #00BA38
7   textrepelgrob7 0.45069445 0.16917609          Duster 360 #619CFF
8   textrepelgrob8 0.46260595 0.61448064           Merc 240D #F8766D
9   textrepelgrob9 0.39856541 0.55258901            Merc 230 #F8766D
10 textrepelgrob10 0.63095101 0.45031424            Merc 280 #00BA38
11 textrepelgrob11 0.41437895 0.32996888           Merc 280C #00BA38
12 textrepelgrob12 0.66711010 0.30496770          Merc 450SE #619CFF
13 textrepelgrob13 0.50014773 0.28200922          Merc 450SL #619CFF
14 textrepelgrob14 0.67525289 0.24128289         Merc 450SLC #619CFF
15 textrepelgrob15 0.87370384 0.07254540  Cadillac Fleetwood #619CFF
16 textrepelgrob16 0.78493872 0.02403392 Lincoln Continental #619CFF
17 textrepelgrob17 0.88648981 0.18453590   Chrysler Imperial #619CFF
18 textrepelgrob18 0.23247238 0.92390399            Fiat 128 #F8766D
19 textrepelgrob19 0.09650626 0.84659168         Honda Civic #F8766D
20 textrepelgrob20 0.22197729 0.97595254      Toyota Corolla #F8766D
21 textrepelgrob21 0.16390043 0.49792044       Toyota Corona #F8766D
22 textrepelgrob22 0.29777168 0.27518655    Dodge Challenger #619CFF
24 textrepelgrob24 0.61358387 0.13037701          Camaro Z28 #619CFF
25 textrepelgrob25 0.71032131 0.40227213    Pontiac Firebird #619CFF
26 textrepelgrob26 0.11647053 0.67208694           Fiat X1-9 #F8766D
27 textrepelgrob27 0.16380659 0.62167544       Porsche 914-2 #F8766D
28 textrepelgrob28 0.09071309 0.79198211        Lotus Europa #F8766D
29 textrepelgrob29 0.38834217 0.22712445      Ford Pantera L #619CFF
30 textrepelgrob30 0.16533637 0.38025663        Ferrari Dino #00BA38
31 textrepelgrob31 0.62150025 0.19322940       Maserati Bora #619CFF
32 textrepelgrob32 0.34441118 0.50204829          Volvo 142E #F8766D
ggplot(mtcars,
            aes(wt, mpg, label = rownames(mtcars), colour = factor(cyl))) +
  geom_point() +
  geom_text(
    aes(x = I(x), y = I(y), label = label, color = I(colour)),
    data = repel_df
  )