我是初学者ggplot2
.所以,如果这个问题听起来太基本,我道歉.我很感激任何指导.我已经花了4个小时来看这个SO线程R:多层ggplot的自定义图例作为指导,但最终无处可去.
目标:我希望能够将图例应用于用于不同图层的不同填充颜色.我正在做这个例子只是为了测试我对应用概念ggplot2
概念的理解.
还有,我不希望改变形状类型; 改变填充颜色很好 - 通过"填充"我并不是说我们可以改变"颜色".所以,如果你能纠正我工作中的错误,我将不胜感激.
尝试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
Run Code Online (Sandbox Code Playgroud)
现在,此图像存在一些问题:
问题1)显示"高mpg区域"的青色矩形已经失去了它的传奇.
问题2) ggplot尝试组合两个geom_point()
图层的图例,因此两者的图例geom_point()
也是混合的.
问题3)使用的默认颜色paleltte ggplot2
使我的眼睛无法区分颜色.
所以,我采取了手动设置颜色iestart与上面的固定#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"))
Run Code Online (Sandbox Code Playgroud)
这是输出:
不幸的是,上面强调的一些问题仍然存在.有关订购的新问题.
问题#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
Run Code Online (Sandbox Code Playgroud)
所以,我有两个问题:
问题1:如何修复图例 - 我想要三个不同的图例 - 一个用于矩形填充(我称之为高mpg矩形),另一个用于填充geom_point()
表示,mtcars$vs
最后一个用于填充geom_point()
表示mtcars$cyl
问题2:我的假设是关于颜色的排序是否正确(即上面讨论的问题#4)?我很怀疑,因为如果有很多因素,我们需要记住它们,然后根据绘制的图层对它们进行排序,最后还是记得按照每个geom_*()
图层的顺序手动应用调色板吗?
作为一个初学者,我花了很多时间在这上面,谷歌搜索到处都是.所以,我很感激你的善意指导.
Mar*_*son 12
(注意,我编辑了这个以便在几次来回之后进行清理 - 请参阅修订历史以了解更多我尝试过的内容.)
标度实际上是为了显示一种类型的数据.一种方法是同时使用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)))
Run Code Online (Sandbox Code Playgroud)
以下是我认为对几乎所有用例都会更好的情节:
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")
Run Code Online (Sandbox Code Playgroud)
出于某种原因,你坚持使用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)))
Run Code Online (Sandbox Code Playgroud)
因为我显然不能单独留下这一点 - 这是另一种方法,只使用填充美学,然后为单个图层制作单独的图例,并使用cowplot
松散地遵循本教程将它们拼接在一起.
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))
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,结果几乎与我演示如何执行此操作的第一种方式相同,但现在不使用任何其他美学.我仍然不明白为什么你认为这种区别是重要的,但至少现在有另一种方法可以给猫皮肤.我可以使用这种方法的一般性(例如,当多个绘图共享颜色/符号/线型美学的混合并且您想要使用单个图例时)但我认为在此处使用它没有任何价值.