ggplot中多个填充的传说

wat*_*wer 8 r ggplot2

我是初学者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

(注意,我编辑了这个以便在几次来回之后进行清理 - 请参阅修订历史以了解更多我尝试过的内容.)

标度实际上是为了显示一种类型的数据.一种方法是同时使用colfill,可以让你至少2个传说.然后linetype,您可以使用添加和破解它override.aes.值得注意的是,我认为这可能(通常)会引发更多问题,而不是解决问题.如果你迫切需要这样做,你可以(例如下面的例子).但是,如果我能说服你:我恳请你尽可能使用这种方法.映射到不同的事物(例如shapelinetype)可能会减少混淆.我举一个下面的例子.

此外,在手动设置颜色或填充时,最好使用命名向量,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)

在此输入图像描述

正如您所看到的,结果几乎与我演示如何执行此操作的一种方式相同,但现在不使用任何其他美学.我仍然不明白为什么你认为这种区别是重要的,但至少现在有另一种方法可以给猫皮肤.我可以使用这种方法的一般性(例如,当多个绘图共享颜色/符号/线型美学的混合并且您想要使用单个图例时)但我认为在此处使用它没有任何价值.

  • **你:**"我想用钉子连接这些板子,但是我的锤子在一定程度上破坏了."**我:**"套件附带的工具箱包括螺丝和胶水;您可以使用它们."**你:**"不,我需要用指甲."**我:**"好的,很好,然后这是一种使用不同的工具来驱动指甲的方法."**你:**"不,我需要使用锤子."**我:**"为什么?"**你:**"因为."**我:**"这是一个坏主意,但这里是如何使用锤子的手柄来做到这一点"**你:**"不,我需要使用锤子*正好*预先在我问"**我:**"之前我想到的想法 (4认同)
  • 有关使用两者的示例,请参阅我最近的编辑.不要将自己锁定在一种方法中(例如,"填充") - 如果你正在尝试做"ggplot"未明确制作的事情,你可能不得不将事情搞得一团糟.如果你有某种原因(赌注?学校作业?)为什么你不能使用`col`和`linetype`,那么让我们知道(也许看看`cowplot`包或`gridExtra`作为@TylerRinker建议) . (2认同)

Dro*_*sof 5

现在有很棒的ggnewscale包允许以简单的方式做到这一点。