ggplot中的多个填充的图例 [英] Legends for multiple fills in ggplot
问题描述
我是 ggplot2
的初学者。所以,如果这个问题听起来太简单,我很抱歉。我会很感激任何指导。我已经花了4个小时在这个,看着这个SO线程
现在,这张图片存在一些问题:
问题1)显示高mpg区域的青色长方形已经失去了它的图例。
问题2) ggplot tr结合两个 geom_point()
图层中的图例,并作为结果为两个 geom_point()
第3期) 使用的默认颜色paleltte使得
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 =平均值(范围(mtcars $ disp)),ymin = 25,alpha = 0.02)+
scale_fill_manual(values = c (绿色,蓝色,黑色,青色,红色,橙色),
标签= c(四档,六档,八档输入:
$ b
不幸的是,上面强调的一些问题仍然存在。有关于订购的新问题。
问题#4:在我看来,
ggplot2
期望我提供颜色按顺序设置图层。即首先将颜色设置为mtcars $ vs
填充,然后mtcars $ cyl ggplot(mtcars,aes(disp,mpg))+
geom_point(aes(fill = factor(cyl)),shape = 21,size = 2,aes(fill = factor(vs)),shape = 23,size = 8,alpha = 0.4) )+
geom_rect(aes(xmin = min(disp)-5,ymax = max(mpg)+ 2,fill =cyan),
xmax = mean(mtcars $ disp)) ,ymin = 25,alpha = 0.02)+
scale_fill_manual(values = c(red,orange,green,blue,black,cyan),
labels = c(0,1,4档,6档,8档,高mpg))#改变订单
所以,我有两个问题:
问题1:修正传说 - 我想要三个不同的传说 - 一个用于矩形填充(我称之为高mpg矩形),另一个用于填充
geom_point()
,由mtcars $ vs
,最后一个为geom_point()
的填充mtcars $ cyl
问题2:我的假设是根据图层的颜色排序是否正确。上面讨论的问题#4)?我怀疑,因为如果有很多因素 - 我们是否需要记住它们,然后根据绘制的图层对它们进行排序,最后记住按照
geom _ *( )
图层被创建?
作为初学者,我花了很多时间在这个网站上搜索每个地方。所以,我会很感激你的指导。
解决方案即将到来 - 请参阅我尝试过的更多修订历史记录。)
这些比例尺实际上意味着显示一种类型的数据。一种方法是使用
col
和fill
,这可以让你至少有2个传说。然后你可以添加linetype
并使用override.aes
来修改它。值得注意的是,我认为这可能(通常)会导致更多的问题而不是解决问题。如果你迫切需要这样做,你可以(下面的例子)。不过,如果我能说服你:我恳求你不要尽可能使用这种方法。映射到不同的东西(例如shape
和linetype
)很可能会导致混淆。我给出了一个下面的例子。
另外,当手动设置颜色或填充时,对
调色板使用命名向量总是一个好主意
确保颜色符合您的要求。
ggplot(mtcars,aes(x = disp
)如果没有,则匹配按照因子级别的顺序发生。 ,y = mpg))+
##地区为高mpg
geom_rect(aes(linetype =High MPG)
,xmin = min(mtcars $ disp)-5
,ymax = max(mtcars $ mpg)+ 2
,fill =cyan
,xmax =平均值(范围(mtcars $ disp))
,ymin = 25
,alpha = 0.02
,col =black)+
##测试差异区域
geom_rect(aes(linetype =Other Region)
,xmin = 300
,xmax = 400
,ymax = 30
,ymin = 25
,fill =yellow
,alpha = 0.02
,col =black )+
geom_point(aes(col =因子(cyl)),形状= 19(aes(col =因子(cyl)),形状= 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
$ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b,ymax = max(mtcars $ mpg)+ 2
,fill = NA
,xmax =平均值(范围(mtcars $ disp))
,ymin = 25
, (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(值= c(High MPG=dotted
,Other Region=dashed)
,name =Region)
出于某种原因,您坚持使用
填
。这是一种使正好与此答案中的第一个图相同的方法,但使用fill
作为每个图层的美学。如果这不是你所坚持的,那么我仍然不知道你在找什么。ggplot (aes(linetype =High MPG)
,xmin(mtcars,aes(x = disp
,y = mpg))+
##高地区的地区
geom_rect = min(mtcars $ disp)-5
,ymax = max(mtcars $ mpg)+ 2
,fill =cyan
,xmax = mean(范围(mtcars $ disp))
,ymin = 25
,alpha = 0.02
,col =black)+
##测试差异区域
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=黑色
,青色=青色)
,名称=V / S
,标签= c(0,1,高级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)))
$ / pre
因为我显然不能离开这一点 - 这是另一种使用填充美学的方法,然后使用cowplot
将这些单独图层的单独图例拼接在一起,松散地跟在
正如您所看到的,结果几乎与<第一种方法,我演示了如何做到这一点,但现在不使用任何其他美学。我仍然不明白你为什么认为这种区分很重要,但至少现在有另一种方法来剥皮猫。我可以使用这种方法的一般性(例如,当多个地块共享颜色/符号/线型美学的组合,并且您想使用单个图例时),但在这里使用它看不出任何价值。
I am a beginner in
ggplot2
. So, I apologize if this question sounds too basic. I'd appreciate any guidance. I've spent 4 hours on this and looked at this SO thread R: Custom Legend for Multiple Layer ggplot for guidance, but ended up nowhere.Objective: I want to be able to apply legend to different fill colors used for different layers. I am doing this example just for the sake of testing my understanding of applying concepts
ggplot2
concepts.Also, I do NOT want to change the shape type; changing fill colors is fine--by "fill" I do not mean that we could change "color". So, I would appreciate if you can correct my mistakes in my work.
Try 1: Here's the bare bones code without any colors set manually.
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
The output looks like this:
Now, there are a few problems with this image:
Issue 1) The cyan rectangle that shows "high mpg areas" has lost its legend.
Issue 2) ggplot tries to combine the legend from the two
geom_point()
layers and as a result the legend for the twogeom_point()
are also mixed.Issue 3) The default color paleltte used by
ggplot2
makes the colors non-distinguishable for my eyes.So, I took a stab at manually setting the colors i.e.start with fixing #3 above.
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"))
Here's the output: Unfortunately, some of the problems highlighted above persist. There is new issue about ordering.
Issue#4: It seems to me that
ggplot2
expects me to provide colors in the order the layers were set. i.e. first set the color formtcars$vs
fill, thenmtcars$cyl
fill and finally the rectangle with cyan color. I was able to fix it by modifying the code to: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
So, I have two questions:
Question 1: How do I fix the legends--I want three different legends--one for rectangle fill (which I call high mpg rectangle), another one for fill for
geom_point()
represented bymtcars$vs
and the last one for fill forgeom_point()
represented bymtcars$cyl
Question2: Is my hypothesis about ordering of colors as per the layers correct (i.e. Issue#4 discussed above)? I am doubtful because what if there are a lot of factors--are we required to memorize them, then order them as per the layers drawn and finally remember to apply color palette manually in the order each
geom_*()
layers are created?As a beginner, I have spent a lot many hours on this, googling everywhere. So, I'd appreciate your kind guidance.
解决方案(Note, I edited this to clean it up after a few back and forths -- see the revision history for more of what I tried.)
The scales really are meant to show one type of data. One approach is to use both
col
andfill
, that can get you to at least 2 legends. You can then addlinetype
and hack it a bit usingoverride.aes
. Of note, I think this is likely to (generally) lead you to more problems than it will solve. If you desperately need to do this, you can (example below). However, if I can convince you: I implore you not to use this approach if at all possible. Mapping to different things (e.g.shape
andlinetype
) is likely to lead to less confusion. I give an example of that below.Also, when setting colors or fills manually, it is always a good idea to use named vectors for
palette
that ensure the colors match what you want. If not, the matches happen in order of the factor levels.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)))
Here is the plot I think will work better for nearly all use cases:
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")
For some reason, you insist on using
fill
. Here is an approach that makes exactly the same plot as the first one in this answer, but usesfill
as the aesthetic for each of the layers. If this isn't what you are insisting on, then I still have no idea what it is you are looking for.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)))
Because I apparently can't leave this alone -- here is another approach using just fill for the aesthetic, then making separate legends for the single layers and stitching it all back together using
cowplot
loosely following this 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))
As you can see, the outcome is nearly identical to the first way that I demonstrated how to do this, but now does not use any other aesthetics. I still don't understand why you think that distinction is important, but at least there is now another way to skin a cat. I can uses for the generalities of this approach (e.g., when multiple plots share a mix of color/symbol/linetype aesthetics and you want to use a single legend) but I see no value in using it here.
这篇关于ggplot中的多个填充的图例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!