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)
CodePudding user response:
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 group
s:
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)