r-在方框图的中心对齐重叠的点,并用线连接这些点



我正在绘制一个方框图,上面覆盖着点,线连接着两个时间集之间的点,下面提供了示例数据。

我有两个问题:

  1. 我希望这些点看起来像这样,只有一点高度抖动和更多宽度抖动。然而,我希望这些点对称地集中在每个y轴标签上方框图的中间(以使图在视觉上更美观(。例如,我想要y=4和x="0"处的6个数据点;然后以与中心对称的距离放置在箱图中心的右侧3个和中心的左侧3个。

  2. 此外,我希望这些线与正确的点连接,但现在这些线的起点和终点都不正确。我知道我可以在geom_point((和geom_line((中使用position=position_dodge((来获得正确的位置,但我也希望能够按高度调整点(为什么点和线与position_dod((对齐,而与position_jitter不对齐?(。

这些事情有可能实现吗?

谢谢!

examiner <- rep(1:15, 2)
time <- rep(c("before", "after"), each = 15)
result <- c(1,3,2,3,2,1,2,4,3,2,3,2,1,3,3,3,4,4,5,3,4,3,2,2,3,4,3,4,4,3)
data <- data.frame(examiner, time, result)
ggplot(data, aes(time, result, fill=time)) + 
geom_boxplot() +
geom_point(aes(group = examiner), 
position = position_jitter(width = 0.2, height = 0.03)) +
geom_line(aes(group = examiner), 
position = position_jitter(width = 0.2, height = 0.03), alpha = 0.3)

我不确定你是否能同时满足这两个问题。

  1. 你可以拥有更多的"对称的";使用geom_dotplot抖动,如下所示:
ggplot(data, aes(time, result, fill=time)) + 
geom_boxplot() +
geom_dotplot(binaxis="y", aes(x=time, y=result, group = time), 
stackdir = "center", binwidth = 0.075)

问题是,当添加线时,它们将在原始的、未抖动的点处连接。

  1. 要将抖动点与映射到抖动点的线连接,可以在绘制之前将抖动添加到数据中。正如你所看到的,抖动最终都会导致点和线不匹配。有关更好的解释,请参见ggplot中的将分组点与线连接
library(dplyr)
data <- data %>% 
mutate(result_jit = jitter(result, amount=0.1),
time_jit = jitter(case_when(
time == "before" ~ 2,
time == "after" ~ 1
), amount=0.1)
)

ggplot(data, aes(time, result, fill=time)) + 
geom_boxplot() +
geom_point(aes(x=time_jit, y=result_jit, group = examiner)) +
geom_line(aes(x=time_jit, y=result_jit, group = examiner), alpha=0.3)

结果

可以使用ggplot_build((从geom_dotplot中提取转换的点-请参阅是否可以获得转换的绘图数据?(例如点图中的点坐标、密度曲线(

这些点可以合并到原始数据上,用作geom_line的锚点。

综合起来:

library(dplyr)
library(ggplot2)
examiner <- rep(1:15, 2)
time <- rep(c("before", "after"), each = 15)
result <- c(1,3,2,3,2,1,2,4,3,2,3,2,1,3,3,3,4,4,5,3,4,3,2,2,3,4,3,4,4,3)
# Create a numeric version of time
data <- data.frame(examiner, time, result) %>% 
mutate(group = case_when(
time == "before" ~ 2,
time == "after" ~ 1)
)
# Build a ggplot of the dotplot to extract data
dotpoints <- ggplot(data, aes(time, result, fill=time)) + 
geom_dotplot(binaxis="y", aes(x=time, y=result, group = time), 
stackdir = "center", binwidth = 0.075)
# Extract values of the dotplot
dotpoints_dat <- ggplot_build(dotpoints)[["data"]][[1]] %>% 
mutate(key = row_number(),
x = as.numeric(x),
newx = x + 1.2*stackpos*binwidth/2) %>% 
select(key, x, y, newx)
# Join the extracted values to the original data
data <- arrange(data, group, result) %>% 
mutate(key = row_number())
newdata <- inner_join(data, dotpoints_dat, by = "key") %>% 
select(-key)
# Create final plot
ggplot(newdata, aes(time, result, fill=time)) + 
geom_boxplot() +
geom_dotplot(binaxis="y", aes(x=time, y=result, group = time), 
stackdir = "center", binwidth = 0.075) +
geom_line(aes(x=newx, y=result, group = examiner), alpha=0.3)

结果

最新更新