I want to draw a bar chart with three columns, where two arrows start from one column to the other two columns and these arrows do not overlap each other, as shown below.
I managed to produce the chart and I used geom_segment
s to draw the arrows. However, the arrows overlap when they start from the column control
.
I thought I could handle the problem by setting geom_segment(..., position = position_nudge(x = 0.25))
. However, this changes not only the position of x
but also xend
. Then, how should I slightly change geom_segment
's position of x
only, keeping the position of xend
constant?
library(tidyverse)
demoData <- tribble(
~priming, ~rt,
"control", 374,
"phonological", 267,
"orthographic", 304
) |>
mutate(
diff.from.baseline = rt - first(rt)
)
baseline <- demoData |>
filter(priming == "control") |>
dplyr::select(rt) |>
pull()
demoData |>
ggplot(
aes(
x = priming,
y = rt
)
) +
geom_col() +
#### from control to orthographic
geom_segment(
aes(
x = "control",
y = baseline,
xend = "control",
yend = baseline + 50
)#,
#position = position_dodge2(
# width = 0.5,
# preserve = "total"
# )
#position = position_nudge(
# x = 0.25,
# xend = 0
#)
) +
geom_segment(
aes(
x = "control" + 0.25,
y = baseline + 50,
xend = "orthographic",
yend = baseline + 50
)#,
#position = position_dodge2(
# width = 1,
# preserve = "total"
# )
#position = position_nudge(
# x = 0.25,
# xend = 0
#)
) +
geom_segment(
aes(
x = "orthographic",
y = baseline + 50,
xend = "orthographic",
yend = demoData |>
filter(priming == "orthographic") |>
dplyr::select(rt) |>
pull()
),
arrow = arrow()
) +
#### from control to phonological
geom_segment(
aes(
x = "control",
y = baseline,
xend = "control",
yend = baseline + 100
)
) +
geom_segment(
aes(
x = "control",
y = baseline + 100,
xend = "phonological",
yend = baseline + 100
)
) +
geom_segment(
aes(
x = "phonological",
y = baseline + 100,
xend = "phonological",
yend = demoData |>
filter(priming == "phonological") |>
dplyr::select(rt) |>
pull()
),
arrow = arrow()
)
Here's an approach:
segments <- data.frame(seg = rep(c(1:2), each = 4),
x = c(0.8, 0.8, 3, 3, 1.2, 1.2, 2, 2),
y = c(as.numeric(demoData[1,2]), 450,
450, as.numeric(demoData[3,2]),
as.numeric(demoData[1,2]), 425,
425, as.numeric(demoData[2,2])))
ggplot() +
geom_path(data = segments, aes(x, y, group = seg), arrow = arrow()) +
geom_col(data = demoData,
aes(x = as.numeric(factor(demoData$priming,
levels = demoData$priming)), rt)) +
scale_x_continuous(breaks = 1:3, labels = demoData$priming)