将geom_point和geom_line与position_jitterdodge相结合,用于两个分组因素。

5

我尝试了几个建议,这些建议基于这里的几篇文章,以及阅读ggplot2文档,但是这个问题略有不同,我还没有找到解决方案。

以下是一个代码片段,用于创建类似于我正在处理的熔化数据框:

a <- c(1,2,3,4,5,6,1,2,3,4,5,6)
b <- c("loss", "draw", "win", "draw", "loss", "win", "loss", "draw", "win", "draw", "loss", "win")
c <- c(2,3,5,4,4,5,4,4,3,5,2,4)
d <- c(rep("x", 6), rep("y", 6))
temp <- data.frame(a,b,c,d)

我想创建一个点图,横轴为b,纵轴为c,横轴上的点按d分组,它们之间用a分组的线连接。如果我们只是将点放在图表上,它看起来很好:
ggplot(temp, aes(x=b, y=c, fill=d, colour=d))+
  geom_point(position=position_jitterdodge())

这是我得到的点图,它看起来就是我想要的样子。 点根据因素d进行颜色编码,并且它们被抖动并排放置,以便x在左侧,y在右侧。

现在,我只想根据因素a用线连接这些点。 这是我在 MS Paint 中制作的模拟版本,它应该是这个样子。添加一个geom_line并将geom_line分组设置为a应该有效...

ggplot(temp, aes(x=b, y=c, fill=d, colour=d))+
  geom_point(position=position_jitterdodge())+
  geom_line(aes(group=a),position=position_jitterdodge())

我尝试连接正确的点,但是它并没有得到正确的结果。它创建的线条长度适合连接正确的点,但它们几乎没有接触到它们,看起来它们随机出现在图表上。我想添加另一个截屏,但我还没有权限。

此外,如果我将组美学更改为整体美学,就像这样:

ggplot(temp, aes(x=b, y=c, fill=d, colour=d, aes(group=a)))+
  geom_point(position=position_jitterdodge())+
  geom_line(position=position_jitterdodge())

然后点会被交换到错误的位置。而且无论如何,线条仍然无法完全连接到点上。
我还尝试在position_jitterdodge()部分中指定width和jitter.width值,但线条和点仍然无法正确连接。我也阅读了ggplot2文档、几个之前的stackoverflow问题,并尝试了大多数position_jitter、position_dodge、geom_jitter等组合,但目前还没有成功。
非常感谢任何帮助。
2个回答

3

您可以使用db之间的交互:

p <- ggplot(temp, aes(x=interaction(d, b), y=c, fill=d, colour=d))+ theme_classic()+
    geom_point()
p + geom_line(aes(group=a),colour=1)

使用正确的x轴。将x转换为数字并设置新标签。

p <- ggplot(temp, aes(x=as.numeric(interaction(d,b)), y=c, fill=d, colour=d))+ theme_classic()+
     geom_point()
p <- p + geom_line(aes(group=a),colour=1)
p +  scale_x_continuous(breaks = c(1.5,3.5,5.5), labels = levels(temp$b))

enter image description here


嗨Jimbou,这是一个很棒的答案,非常感谢!为了让它对我起作用,只需要对你的代码进行一点小修改 - 在最后一行将d1$b更改为temp$b以获取x轴上的标签:p + scale_x_continuous(breaks = c(1.5,3.5,5.5), labels = levels(temp$b)) - GFL
1
@GFL已经修复了。谢谢。 - Roman

1

一种可能的解决方案 - 手动指定抖动值:

library(ggplot2)

a <- c(1,2,3,4,5,6,1,2,3,4,5,6)
# b <- c("loss", "draw", "win", "draw", "loss", "win", "loss", "draw", "win", "draw", "loss", "win")
b <- c(2, 1, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3)
c <- c(2, 3, 5, 4, 4, 5, 4, 4, 3, 5, 2, 4)
d <- c(rep("x", 6), rep("y", 6))
temp <- data.frame(a,b,c,d)

set.seed(2016)
jitterVal <- runif(12, max = 0.25)
jitterVal <- jitterVal * ifelse(temp$d == "x", -1, +1)

ggplot(temp, aes(x = b + jitterVal, y = c, fill = d, colour = d)) +
  geom_point() +
  geom_line(aes(group = a)) +
  scale_x_continuous(breaks = c(1, 2, 3), labels = c("draw", "loss", "win")) +
  xlab(NULL) +
  expand_limits(x = c(0.5, 3.5))

谢谢,这个完美地解决了问题。虽然每次都这样做不是理想的选择,但肯定比让点和线到处乱跑要好得多。 - GFL
1
你可以将这个代码块封装成一个函数,简单的 jitterVal <- runif(nrow(temp), max = 0.25) 再加上 scale_x_continuous 的断点和标签就足以让它自动工作了。 - m-dz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接