0

Context

I used ggplot to draw a grouped error bar graph. I want to connect the points with lines within each group.

I tried to use geom_line(), but the result is not what I want.

Question

Is there any way to connect the points within each group with a line, like the red line in the figure below.

Reproducible Code

dat_a = structure(list(exposure = c("HDL", "HDL", "HDL", "HDL", "HDL", 
"HDL", "HDL", "HDL", "HDL"), event = c("mRS", "mRS", "mRS", "mRS", 
"mRS", "mRS", "mRS", "mRS", "mRS"), model = structure(c(1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L), levels = c("low", "middle", "high"
), class = "factor"), group = c("middle", "low", "high", "middle", 
"low", "high", "middle", "low", "high"), margin = c(0.292, 0.372, 
0.349, 0.25, 0.336, 0.281, 0.252, 0.35, 0.278), LL = c(0.273, 
0.327, 0.308, 0.23, 0.287, 0.235, 0.226, 0.285, 0.22), UL = c(0.311, 
0.417, 0.391, 0.27, 0.385, 0.326, 0.278, 0.415, 0.336)), row.names = c(NA, 
-9L), class = c("tbl_df", "tbl", "data.frame"))

pd = position_dodge(.7)

ggplot(dat_a, aes(colour=group, y=margin, x=model, group=group))+
  geom_point(position=pd,shape=16,size=4)+
  geom_errorbar(aes(ymax = UL, ymin=LL), position=pd,width=0.2,size=1.1)+
  labs(title = "", x="", y="Marginal probability of poor prognosis") +
  guides(color=guide_legend(title="HDL cholesterol level"))+
  scale_color_jama()+
  theme_classic()+
  theme(axis.title =element_text(size=14),axis.text = element_text(size = 12),
        legend.text=element_text(size=12),legend.title = element_text(size=12),
        legend.position = 'right')+ ylim(0.2,0.5)

enter image description here

1 Answer 1

1

Dodging and lines is always a bit tricky. The issue is that on the one hand we want the lines to be grouped by model but on the other hand we want them to be grouped by group for the dodging. TBMK there is no way to achieve that via dodging and the group aes. Instead I would go for manual dodging which requires to compute the x positions for the geom_line manually. To this end convert your model and group columns to numerics first. Second, rescale the group_num to a range of -1 to 1. This resealed column will be used to "shift" the points for each category of model. Third, compute the amount of the shift which is simply the width used for dodging divided by the number of groups:

enter image description here

library(ggplot2)
library(ggsci)

dw <- .7
dw_line <- dw / length(unique(dat_a$group))
pd <- position_dodge(width)

dat_a$model_num <- as.numeric(factor(dat_a$model))
dat_a$group_num <- as.numeric(factor(dat_a$group))
dat_a$group_num <- scales::rescale(dat_a$group_num, to = c(-1, 1))

ggplot(dat_a, aes(colour = group, y = margin, x = model, group = group)) +
  geom_point(position = pd, shape = 16, size = 4) +
  geom_errorbar(aes(ymax = UL, ymin = LL), position = pd, width = 0.2, size = 1.1) +
  geom_line(aes(x = model_num + dw_line * group_num, group = model), color = "red", size = 2) +
  labs(title = "", x = "", y = "Marginal probability of poor prognosis") +
  guides(color = guide_legend(title = "HDL cholesterol level")) +
  scale_color_jama() +
  theme_classic() +
  theme(
    axis.title = element_text(size = 14), axis.text = element_text(size = 12),
    legend.text = element_text(size = 12), legend.title = element_text(size = 12),
    legend.position = "right"
  ) +
  ylim(0.2, 0.5)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.