ggplot图例:geom_abline干扰问题

3

目标:为geom_point创建一个颜色图例,每个组用不同的颜色点表示,并为geom_abline创建一个图例,每条线用不同的颜色表示。

我做错了什么?有没有解决方案?

# data: mtcars + some made-up straight lines
library(ggplot2)
df = data.frame(Intercept = c(2,3,4), Slope = c(0,0,0), Group = factor(c(1, 2, 3)))

#1的评论: 基本情节没有什么特别之处,但是我已经将数据分组在aes()内,并使颜色成为一个 aes()。我认为在aes()中同时使用“group”和“color”是标准的做法,以实现分组和着色。

# 1. my basic plot
ggplot(data = mtcars, aes(x = mpg, y = wt, group = vs, color = factor(vs))) + 
    geom_point() -> p

关于#2的评论: 明显我的ggplot设置不正确,无法正确处理图例。我还尝试在aes中添加group = Group。但是有一个更严重的问题: geom_point形成了2个组,geom_abline形成了3个组,但是图例只显示了4种颜色/线条组合。其中一个已经被合并了(绿色的)。我做错了什么?

# 2. my naive attempt to add ablines of 3 different colours
p + geom_abline(data = df, aes(intercept = Intercept, slope = Slope,
                           colour = Group))

这里输入图片描述

关于#3的评论:虽然图例中去掉了ablines,但点仍然不对。从这里开始会变得越来越绝望。

# 3. Suppress the ab_line legend?
p + geom_abline(data = df, aes(intercept = Intercept, slope = Slope,
                           colour = Group), show.legend = FALSE)

enter image description here

#4的评论:目前我正在努力达成这个目标。比错误的图例好的多。不过失去颜色还是有点遗憾。

# 4. Remove the geom_abline legend AND colors
p + geom_abline(data = df, aes(intercept = Intercept, slope = Slope))

enter image description here

评论 #5:我不知道我在这里希望什么......如果我在geom_point()的调用中定义数据和aes,而不是在ggplot()中定义,那么geom_abline()似乎不会劫持颜色和图例,但实际上并没有任何区别。

# 5. An attempt to set the aes inside geom_point() instead of ggplot()
ggplot() + 
    geom_point(data = mtcars, aes(x = mpg, y = wt, group = vs, color = factor(vs))) + 
    geom_abline(data = df, aes(intercept = Intercept, slope = Slope, color = "groups")) +
    scale_color_manual(values = c("red", "blue", "black"))

enter image description here


不确定这是否有帮助。您的两个数据集中有4个不同的分组变量。在 mtcars 中,您有0-1变量 vs,而在您的数据 df 中,则有级别为1、2、3的 Group。当您将 df 中的 Group 级别更改为例如 A、B、C 时,您将获得5种不同的颜色。这是一种巧妙的解决方案,因为我希望 geom_ablinegeom_point 可以使用不同的数据集。 - Adela
ggplot表现如预期,显示了因子水平。尝试删除缺失的水平(droplevels)。 - Roman Luštrik
1
@Adela,谢谢!我明白了:“ggplot”看不出“mtcars”的“1”和“df”的“1”是不同的。我想知道这是否是预期的或功能上的限制。 - PatrickT
@RomanLuštrik,谢谢。我应该删除哪些级别?从“df”中,我有“Group:Factor w / 3 levels"1","2","3": 1 2 3”,而从“mtcars”中,我有“Factor w / 2 levels"0","1": 1 1 2 2 1 2 1 2 2 2”。显然,“df”和“mtcars”都有“1”作为共同的级别。我该删掉什么? - PatrickT
2个回答

5

一种选择是使用填充形状对mtcars数据进行处理,这样你可以有一个fill比例尺和一个colour比例尺,而不是两个colour比例尺。如果您不想要黑色的轮廓线,请在geom_point语句中添加选项colour="white"以更改点的边缘颜色。

library(ggplot2)
df = data.frame(Intercept = c(2,3,4), Slope = c(0,0,0), Group = factor(c(1, 2, 3)))
ggplot(data = mtcars, aes(x = mpg, y = wt, group = vs, fill = factor(vs))) + 
           geom_point(shape=21, size=2) +
           geom_abline(data = df, aes(intercept = Intercept, slope = Slope,
                              colour = Group))

enter image description here


1
不错的ggplot编程技巧,谢谢!我想我们在这里提出了几个问题。一:当从带有相同级别的不同变量的不同数据框中进行分组时(这里是“1”),ggplot会感到困惑。二:ggplot不能将来自不同图形的geom_point图例部分分开,例如它将由geom_point()制作的点与由geom_abline()制作的点视为相同。 - PatrickT
1
有没有办法让图例中的“Group”行水平显示? - Hugues
@Hugues 是的,有一个方法 - 如果你用 geom_hline(data = df, aes(yintercept = Intercept, colour = Group)) 替换 geom_abline 语句(这也意味着你不需要在 df 中定义 Slope)。 - Andrew Gustar
我需要Slope和geom_abline,我只想让图例以水平线的形式呈现,就像图表中通常一样。 - Hugues
1
@Hugues 这可能会有所帮助... https://dev59.com/LJTfa4cB1Zd3GeqPS5Yb - Andrew Gustar
1
它起作用了,需要一些微调。 - Hugues

0
如果您需要或想要在图例中添加一条水平线,可以考虑使用以下代码:
library(ggplot2)
df = data.frame(Intercept = c(2,3,4), Slope = c(0,0,0),
Group = factor(c(1, 2, 3)))
ggplot(data = mtcars,
   aes(x = mpg, y = wt, group = vs, fill = factor(vs))) + 
geom_point(shape=21, size=2) +
geom_hline(data = df,
          aes(yintercept = Intercept,colour = Group))

使用geom_hline绘图


谢谢,但我真的需要“geom_abline”,因为我正在绘制线性分位数。安德鲁提供了一个很好的答案。目前似乎没有更简单的方法来实现这个结果。 - PatrickT

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