我是ggplot2
的初学者。所以,如果这个问题听起来太基本,我道歉。我很感激任何指导。我已经花了4个小时的时间来查看这个SO帖子R: Custom Legend for Multiple Layer ggplot以寻求指导,但最终无处可去。
目标:我希望能够将图例应用于用于不同图层的不同填充颜色。我正在做这个例子只是为了测试我对应用概念ggplot2
概念的理解。
另外,我 NOT 想要改变形状类型;改变填充颜色很好 - 通过"填充"我并不是说我们可以改变颜色"。所以,如果你能纠正我的工作中的错误,我将不胜感激。
尝试1: 这是没有手动设置任何颜色的裸骨代码。
ggplot(mtcars, aes(disp,mpg)) +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4) +
geom_point (aes(fill = factor(cyl)),shape = 21, size = 2) +
geom_rect(aes(xmin = min(disp)-5, ymax = max(mpg) + 2,fill = "cyan"),
xmax = mean(range(mtcars$disp)),ymin = 25, alpha = 0.02) ##region for high mpg
现在,此图片存在一些问题:
问题1)显示"高mpg区域的青色矩形"失去了它的传奇。
问题2) ggplot尝试合并两个geom_point()
图层中的图例,因此两个geom_point()
的图例也会混合。
问题3) ggplot2
使用的默认颜色古板使我的眼睛无法区分颜色。
所以,我采取了手动设置颜色的方法,即上面固定#3开始。
ggplot(mtcars, aes(disp,mpg)) +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4)+
geom_point(aes(fill = factor(cyl)),shape = 21, size = 2) +
geom_rect(aes(xmin = min(disp)-5, ymax = max(mpg) + 2,fill = "cyan"),
xmax = mean(range(mtcars$disp)),ymin = 25, alpha = 0.02) +
scale_fill_manual(values = c("green","blue", "black", "cyan", "red", "orange"),
labels=c("4 gears","6 gears","8 gears","High mpg","0","1"))
这是输出: 不幸的是,上面强调的一些问题仍然存在。有关订购的新问题。
问题#4:在我看来,ggplot2
希望我按照图层设置的顺序提供颜色。即首先设置mtcars$vs
填充的颜色,然后mtcars$cyl
填充,最后设置青色的矩形。我能够通过修改代码来修复它:
ggplot(mtcars, aes(disp,mpg)) +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4) +
geom_point(aes(fill = factor(cyl)),shape = 21, size = 2) +
geom_rect(aes(xmin = min(disp)-5, ymax = max(mpg) + 2,fill = "cyan"),
xmax = mean(range(mtcars$disp)),ymin = 25, alpha = 0.02) +
scale_fill_manual(values = c("red", "orange", "green", "blue", "black", "cyan"),
labels=c("0","1","4 gears","6 gears","8 gears","High mpg")) #changed the order
所以,我有两个问题:
问题1:如何修复图例 - 我想要三个不同的图例 - 一个用于矩形填充(我称之为高mpg矩形),另一个用于填充{{1} }由geom_point()
代表,最后一个代表mtcars$vs
代表geom_point()
问题2:我的假设是关于颜色的排序是否正确(即上面讨论的问题#4)?我很怀疑,因为如果有很多因素,我们需要记住它们,然后按照绘制的图层对它们进行排序,最后还是记得按照每个mtcars$cyl
图层的顺序手动应用调色板吗?
作为初学者,我花了很多时间在这上面,谷歌搜索到处都是。所以,我很感激你的善意指导。
答案 0 :(得分:10)
(注意,我编辑了这个以便在几次来回之后进行清理 - 请参阅修订历史以了解更多我尝试过的内容。)
衡量标准实际上是为了显示一种类型的数据。一种方法是同时使用col
和fill
,这可以使您获得至少2个传说。然后,您可以使用linetype
添加override.aes
并稍微破解它。值得注意的是,我认为这可能(通常)会引发更多问题,而不是解决问题。如果你迫切需要这样做,你可以(例如下面的例子)。但是,如果我可以说服你:我恳求你不尽可能使用这种方法。映射到不同的内容(例如shape
和linetype
)可能会减少混淆。我在下面给出一个例子。
此外,在手动设置颜色或填充时,最好使用palette
的命名向量来确保颜色与您想要的颜色相匹配。如果不是,则匹配按因子级别的顺序发生。
ggplot(mtcars, aes(x = disp
, y = mpg)) +
##region for high mpg
geom_rect(aes(linetype = "High MPG")
, xmin = min(mtcars$disp)-5
, ymax = max(mtcars$mpg) + 2
, fill = "cyan"
, xmax = mean(range(mtcars$disp))
, ymin = 25
, alpha = 0.02
, col = "black") +
## test diff region
geom_rect(aes(linetype = "Other Region")
, xmin = 300
, xmax = 400
, ymax = 30
, ymin = 25
, fill = "yellow"
, alpha = 0.02
, col = "black") +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4) +
geom_point (aes(col = factor(cyl)),shape = 19, size = 2) +
scale_color_manual(values = c("4" = "red"
, "6" = "orange"
, "8" = "green")
, name = "Cylinders") +
scale_fill_manual(values = c("0" = "blue"
, "1" = "black"
, "cyan" = "cyan")
, name = "V/S"
, labels = c("0?", "1?", "High MPG")) +
scale_linetype_manual(values = c("High MPG" = 0
, "Other Region" = 0)
, name = "Region"
, guide = guide_legend(override.aes = list(fill = c("cyan", "yellow")
, alpha = .4)))
以下是我认为几乎适用于所有用例的情节:
ggplot(mtcars, aes(x = disp
, y = mpg)) +
##region for high mpg
geom_rect(aes(linetype = "High MPG")
, xmin = min(mtcars$disp)-5
, ymax = max(mtcars$mpg) + 2
, fill = NA
, xmax = mean(range(mtcars$disp))
, ymin = 25
, col = "black") +
## test diff region
geom_rect(aes(linetype = "Other Region")
, xmin = 300
, xmax = 400
, ymax = 30
, ymin = 25
, fill = NA
, col = "black") +
geom_point(aes(col = factor(cyl)
, shape = factor(vs))
, size = 3) +
scale_color_brewer(name = "Cylinders"
, palette = "Set1") +
scale_shape(name = "V/S") +
scale_linetype_manual(values = c("High MPG" = "dotted"
, "Other Region" = "dashed")
, name = "Region")
出于某种原因,您坚持使用fill
。这是一种方法,使完全与本答案中的第一个完全相同,但使用fill
作为每个层的美学。如果这不是你所坚持的,那么我仍然不知道你在寻找什么。
ggplot(mtcars, aes(x = disp
, y = mpg)) +
##region for high mpg
geom_rect(aes(linetype = "High MPG")
, xmin = min(mtcars$disp)-5
, ymax = max(mtcars$mpg) + 2
, fill = "cyan"
, xmax = mean(range(mtcars$disp))
, ymin = 25
, alpha = 0.02
, col = "black") +
## test diff region
geom_rect(aes(linetype = "Other Region")
, xmin = 300
, xmax = 400
, ymax = 30
, ymin = 25
, fill = "yellow"
, alpha = 0.02
, col = "black") +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4) +
geom_point (aes(col = "4")
, data = mtcars[mtcars$cyl == 4, ]
, shape = 21
, size = 2
, fill = "red") +
geom_point (aes(col = "6")
, data = mtcars[mtcars$cyl == 6, ]
, shape = 21
, size = 2
, fill = "orange") +
geom_point (aes(col = "8")
, data = mtcars[mtcars$cyl == 8, ]
, shape = 21
, size = 2
, fill = "green") +
scale_color_manual(values = c("4" = NA
, "6" = NA
, "8" = NA)
, name = "Cylinders"
, guide = guide_legend(override.aes = list(fill = c("red","orange","green")))) +
scale_fill_manual(values = c("0" = "blue"
, "1" = "black"
, "cyan" = "cyan")
, name = "V/S"
, labels = c("0?", "1?", "High MPG")) +
scale_linetype_manual(values = c("High MPG" = 0
, "Other Region" = 0)
, name = "Region"
, guide = guide_legend(override.aes = list(fill = c("cyan", "yellow")
, alpha = .4)))
因为我显然不能单独留下这一点 - 这是另一种方法,只使用填充美学,然后为单个图层制作单独的图例,并使用cowplot
松散地将它们拼接在一起tutorial
library(cowplot)
library(dplyr)
theme_set(theme_minimal())
allScales <-
c("4" = "red"
, "6" = "orange"
, "8" = "green"
, "0" = "blue"
, "1" = "black"
, "High MPG" = "cyan"
, "Other Region" = "yellow")
mainPlot <-
ggplot(mtcars, aes(x = disp
, y = mpg)) +
##region for high mpg
geom_rect(aes(fill = "High MPG")
, xmin = min(mtcars$disp)-5
, ymax = max(mtcars$mpg) + 2
, xmax = mean(range(mtcars$disp))
, ymin = 25
, alpha = 0.02) +
## test diff region
geom_rect(aes(fill = "Other Region")
, xmin = 300
, xmax = 400
, ymax = 30
, ymin = 25
, alpha = 0.02) +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4) +
geom_point (aes(fill = factor(cyl)),shape = 21, size = 2) +
scale_fill_manual(values = allScales)
vsLeg <-
(ggplot(mtcars, aes(x = disp
, y = mpg)) +
geom_point(aes(fill = factor(vs)),shape = 23, size = 8, alpha = 0.4) +
scale_fill_manual(values = allScales
, name = "VS")
) %>%
ggplotGrob %>%
{.$grobs[[which(sapply(.$grobs, function(x) {x$name}) == "guide-box")]]}
cylLeg <-
(ggplot(mtcars, aes(x = disp
, y = mpg)) +
geom_point (aes(fill = factor(cyl)),shape = 21, size = 2) +
scale_fill_manual(values = allScales
, name = "Cylinders")
) %>%
ggplotGrob %>%
{.$grobs[[which(sapply(.$grobs, function(x) {x$name}) == "guide-box")]]}
regionLeg <-
(ggplot(mtcars, aes(x = disp
, y = mpg)) +
geom_rect(aes(fill = "High MPG")
, xmin = min(mtcars$disp)-5
, ymax = max(mtcars$mpg) + 2
, xmax = mean(range(mtcars$disp))
, ymin = 25
, alpha = 0.02) +
## test diff region
geom_rect(aes(fill = "Other Region")
, xmin = 300
, xmax = 400
, ymax = 30
, ymin = 25
, alpha = 0.02) +
scale_fill_manual(values = allScales
, name = "Region"
, guide = guide_legend(override.aes = list(alpha = 0.4)))
) %>%
ggplotGrob %>%
{.$grobs[[which(sapply(.$grobs, function(x) {x$name}) == "guide-box")]]}
legendColumn <-
plot_grid(
# To make space at the top
vsLeg + theme(legend.position = "none")
# Plot the legends
, vsLeg, regionLeg, cylLeg
# To make space at the bottom
, vsLeg + theme(legend.position = "none")
, ncol = 1
, align = "v")
plot_grid(mainPlot +
theme(legend.position = "none")
, legendColumn
, rel_widths = c(1,.25))
正如您所看到的,结果几乎与我演示如何执行此操作的 first 方式相同,但现在不使用任何其他美学。我仍然不明白为什么你认为这种区别是重要的,但至少现在有另一种方法可以给猫皮肤。我可以使用这种方法的一般性(例如,当多个绘图共享颜色/符号/线型美学的混合并且您想要使用单个图例时)但我认为在此处使用它没有任何价值。
答案 1 :(得分:0)
现在有了很棒的ggnewscale软件包,可以通过简单的方式完成此操作。
答案 2 :(得分:-1)
您还可以使用align_plots
中的ggdraw
和cowplot
函数分层多个图来实现此目的。这是我用于将散射(离散色标)放到光栅上的解决方案(连续色标)。请参阅以下链接中的插图。
https://www.rdocumentation.org/packages/cowplot/versions/0.9.2/topics/align_plots