首页 文章

手动设置多层图的图例颜色和文本

提问于
浏览
1

在过去的两年里,我一直在使用r开关,而且最近才开始使用ggplot来构建图形 . 我陷入了下面描述的情况:

我有一个多层图,其中所有数据都在初始ggplot调用中引用的相同数据帧中 .

  • 第1层=点数

  • 第2层=平均趋势

  • 第3层=趋势的衍生物

  • 第4层和第5层=给出平均趋势的点的预测间隔

我想要做的是手动调整图例文本以反映每个图层的名称和颜色/ geom(第4层和第5层可以是一个参考) . 当我这样做时,geom_lines的图例都会变回红色 .

另一个问题是我想重命名渐变比例,但是当我这样做时,渐变变成离散点而不是条形 .

ggplot(D_ff_NWn,aes(NW_norm,FF_Det,color = CYC))+
  geom_point()+
  scale_color_gradient(guide = guide_legend(title = "Feeder Cycle"))+
  geom_line(aes(NW_norm,FF10.fit,fill="black"), color="black", show.legend = TRUE) +
  geom_line(aes(NW_norm,Diff1*SCL_rg+SCL_FF[1],fill="red"), 
            color="red", show.legend = TRUE)+
  geom_line(aes(NW_norm,FF_UCL,fill="Prediction"),color="green")+
  geom_line(aes(NW_norm,FF_LCL),color="green")+
  labs(x = "Normalized Net Weight (%)")+
  scale_y_continuous("Feed Factor (g/rev)", 
                     sec.axis = sec_axis(~ (. - SCL_FF[1])/SCL_rg, 
                                         name = "1st Derivative ([g/rev]/%)"))+
  scale_fill_manual(name="",
                    labels = c("Avg FF (g/min)", "1st Derivative","95% Prediction"),
                    values = c("black","red","green"))+ 
  theme(axis.text.y.right = element_text(color = "red"), 
        axis.title.y.right = element_text(color = "red"))

总而言之,我希望有:

  • 我的自定义名称的渐变条得到了第一层

  • 具有自定义名称的每个图层的代表行

Example graph

注意:使用 SCL_FFSCL_rg 缩放第二个y轴

我确信我无法添加足够的数据来生成上面显示的图像,但数据框结构如下所示 .

'data.frame':  16141 obs. of  19 variables:
 $ key                : Factor w/ 6 levels "ATAB","CCNa",..: 1 1 1 1 1 1 1 1 
 1 1 ...
 $ Process_Time       : num  5.65 5.67 5.68 5.7 5.72 ...
 $ CONC_PCT           : num  32 32 31.8 31.7 31.6 ...
 $ STATE              : Factor w/ 4 levels "Blind","Gravimetric",..: 2 2 2 2 
 2 2 2 2 2 2 ...
 $ NW                 : num  1.16 1.15 1.15 1.15 1.15 ...
 $ SRW_SP             : num  56.7 56.4 56.3 56.2 56 ...
 $ FF                 : num  2.36 2.37 2.37 2.37 2.37 ...
 $ MF                 : num  8 7.98 7.95 7.93 7.9 ...
 $ CYC                : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Max_Mass           : num  1.72 1.72 1.72 1.72 1.72 ...
 $ NW_norm            : num  0.673 0.672 0.671 0.67 0.668 ...
 $ FF_Det             : num  2.33 2.33 2.33 2.34 2.34 ...
 $ FF10.fit           : num  2.34 2.34 2.34 2.34 2.34 ...
 $ FF10.se.fit        : num  0.000121 0.000121 0.000121 0.000121 0.000121 
 ...
 $ FF10.residual.scale: num  0.00458 0.00458 0.00458 0.00458 0.00458 ...
 $ FF10.df            : num  16128 16128 16128 16128 16128 ...
 $ Diff1              : num  0.0363 0.0363 0.0361 0.0344 0.0323 ...
 $ FF_UCL             : num  2.35 2.35 2.35 2.35 2.35 ...
 $ FF_LCL             : num  2.34 2.34 2.34 2.34 2.34 ...

有什么我公然缺席的事吗?我以为我对ggplot图层的工作方式有了很好的理解 .

感谢任何帮助或指导 .

Update 07May2018

来自Z.Lin的下述解决方案奏效了 . 我颠倒了渐变条标签,并将“一阶导数”图层更改为指向隐藏“标准化净重”高端的不需要的栅格 .

  • 新图例会生成所有图层的点/线 . 可以调整吗我不明白为什么它必须默认这个

  • 另一个问题是使用形状的边界会从渐变条映射中减去主图 . 它可能没问题,因为主图是在窗口中针对"Normalized Net Weight"而不是"Process Time"绘制的趋势因子的去趋势版本

Updated Plot

enter image description here

ggplot(D_ff_NWn, aes(x = NW_norm))+

  geom_point(aes(y = FF_Det, fill = CYC), shape = 21,stroke = 0.1) +
  geom_point(aes(y = Diff1 * SCL_rg + SCL_FF[1], colour = "1st 
    Derivative"),size=0.5) +
  geom_line(aes(y = FF10.fit, colour = "Avg FF (g/min)")) +
  geom_line(aes(y = FF_UCL, colour = "95% Prediction")) +
  geom_line(aes(y = FF_LCL, colour = "95% Prediction")) +

  labs(x = "Normalized Net Weight (%)")+
  scale_y_continuous(name = "Feed Factor (g/rev)", 
                     sec.axis = sec_axis(~ (. - SCL_FF[1])/SCL_rg, 
                                         name = "1st Derivative ([g/rev]/%)")) +
  scale_fill_gradient(name = "Feeder Cycle",guide = guide_colourbar(reverse = 
                                                                      TRUE))+
  scale_colour_manual(name = "",
                      values = c("Avg FF (g/min)" = "black", 
                                 "1st Derivative" = "red",
                                 "95% Prediction" = "green"))+ 

  theme(axis.text.y.right = element_text(color = "red"), 
        axis.title.y.right = element_text(color = "red"))

1 回答

  • 0

    如果没有实际数据进行测试,这是我对可以为您工作的最佳猜测:

    ggplot(D_ff_NWn, 
           aes(x = NW_norm))+
    
      geom_point(aes(y = FF_Det, fill = CYC), shape = 21, colour = alpha("black", 0)) +
      geom_line(aes(y = FF10.fit, colour = "Avg FF (g/min)")) +
      geom_line(aes(y = Diff1 * SCL_rg + SCL_FF[1], colour = "1st Derivative")) +
      geom_line(aes(y = FF_UCL, colour = "95% Prediction")) +
      geom_line(aes(y = FF_LCL, colour = "95% Prediction")) +
    
      labs(x = "Normalized Net Weight (%)")+
      scale_y_continuous(name = "Feed Factor (g/rev)", 
                         sec.axis = sec_axis(~ (. - SCL_FF[1])/SCL_rg, 
                                             name = "1st Derivative ([g/rev]/%)")) +
      scale_fill_gradient(name = "Feeder Cycle")+
      scale_colour_manual(name = "",
                          values = c("Avg FF (g/min)" = "black", 
                                     "1st Derivative" = "red",
                                     "95% Prediction" = "green"))+ 
    
      theme(axis.text.y.right = element_text(color = "red"), 
            axis.title.y.right = element_text(color = "red"))
    

    如果这样可行,请在下面解释我在您的代码中观察到的几个问题:

    Issue 1 - You want to specify different colour legends for the geom_point() & geom_line() layers

    如果你检查 ?geom_line ,你可以看到 colour 列在它理解的美学中,但 fill 就是它 . 这意味着 geom_line(aes(...)) 中的 fill = red (或其他颜色)线将被忽略 .

    另一方面, geom_point 同时了解 colourfill . 默认的点形状基于 colour 美学而着色,但还有其他形状基于 fill 美学着色,其轮廓基于 colour 美学而非 .

    shapes

    (图片来源于here . 形状21-25接受 fill 的颜色,& colour 的轮廓 . )

    要解决问题1,请选择21-25的形状,使用 aes(fill = CYC) 设置 geom_point 的颜色,并为各自的 geom_line 层保留 aes(colour = something) .

    Issue 2 - The order of the manually stated legend labels is probably wrong

    我知道使用 aes(fill = "some value")scale_fill_manual() 之类的东西可以手动指定美学映射,但代码中值的顺序是:

    • aes(fill = "black") (第2层)

    • aes(fill = "red") (第3层)

    • aes(fill = "Prediction") (第4层)

    而手动秤中的订单是:

    scale_fill_manual(name="", 
                      labels = c("Avg FF (g/min)", "1st Derivative","95% Prediction"),
                      values = c("black","red","green"))
    

    暂时忽略 colourfill 问题,我们可以看到此处列出的值的字母顺序为 c("black", "Prediction", "red"). scale_fill_manual() has no way of knowing that Prediction is supposed to be mapped to green`;它将简单地按字母顺序获取值列表,并将它们按顺序匹配到此处列出的标签/值 .

    要解决问题2,请在 scale_XXX_manual 中使用命名向量作为 values 参数 .

    (我还建议在各个 geom_line(aes(fill = "some value")) 图层中使用标签作为值,并将 labels = c(...)scale_XXX_manual 中删除 . 我认为它更整洁 . )

    Issue 3 - You explicitly asked for a colour legend in discrete points, rather than a colour bar

    ggplot2guide_legendguide_colourbar 中有两个不同的图例相关函数 . 前者创造了一个离散的尺度,而后者则是一个连续的尺度 . 默认情况下, scale_XXX_gradient 实际上使用colourbar选项,但 scale_color_gradient(guide = guide_legend(title = "Feeder Cycle")) 行覆盖了该选项 .

    要解决问题3,您可以:

    • guide_legend(title = "some title") 替换为 guide_colourbar(title = "some title") ,或;

    • 只需将它们全部放在一起,并使用 scale_XXX_gradient(name = "some title") 指定图例名称 .

    (minor) Issue 4 - Top level aesthetic mappings

    在你的代码中,每个 geom 层的审美对于 x ,映射以 NW_norm 开头,然后是 y 的不同变量 .

    由于 x = NW_norm 对所有图层都是通用的,因此应该在顶级 ggplot() 调用中声明,并且 only 在那里 . 除非有本地 aes(x = some.other.variable) 映射来覆盖它,否则所有后续层都将继承该层 .

    由于 y = something 对于每一层都不同,因此不需要它在顶层调用中 . 每个 geom 图层都应该有 y 的美学映射,将 explicitly 命名为 aes(y = something, ...) 而不是 aes(something, ...)

相关问题