【问题标题】:ggplot2 - split one legend (two color scales) and delete anotherggplot2 - 拆分一个图例(两个色标)并删除另一个
【发布时间】:2023-04-05 10:12:01
【问题描述】:

我在ggplot2 中配置情节图例时遇到了很多麻烦。我有两个数据框:

require(ggplot2)
mat <- rep(c("None", "wood", "steel"), each = 4)
feet = rep(seq(0,3), 3)
load = c(3:6, 4:7, 5:8)

soil <- data.frame(
  feet = feet,
  test = rep(1:3, each = 4),
  load = c(0.1, 0.2, 0.3, 0.04,
           0.5, 0.6, 0.7, 0.44,
           0.8, 0.9, 1.0, 0.74)
)

dat <- rbind(
  data.frame(
    feet = feet,
    mat = mat,
    load = c(3:6, 4:7, 5:8),
    SF = FALSE
  ),
  data.frame(
    feet = feet,
    mat = mat,
    load = c(6:9, 7:10, 8:11),
    SF = TRUE
  )
)

我想要一个带有 dat$mat 的图例和 soil$test 的图例的情节:

myplot <- ggplot(dat, aes(x = load, y = feet)) +
  geom_line(aes(color = mat, linetype = SF)) +
  geom_path(dat = soil, aes(x = load, y = feet, color = factor(test)))

myplot

我不想要名为 SF 的图例。另外,我想将名为 mat 的图例拆分为两个图例,mat(值 = "none"、"wood"、"steel")来自 dat data.frame 和 test(值= 1, 2, 3) 来自soil data.frame。

我尝试了theme(legend.position = "none"),以及许多其他各种代码组合,如果我将它们全部列出,它们会填满页面。感谢您提供的任何帮助。

【问题讨论】:

  • 第一个问题使用scale_linetype(guide = FALSE)
  • 我开始相信同一美学不可能有单独的图例
  • @MM 我一直在尝试所有的早晨,至少 8 小时到这个...... ;) 似乎应该有可能看到它们来自不同的表、不同的变量名和不同的绘制它们的函数(即 geom_line vs geom_path)
  • 但他们使用相同的 aes,即颜色。如果您搜索,您会看到许多分别带有填充和颜色的 geom bar 和 geom line 示例。我能够为其中一个在 aes 之外添加颜色,并且只为一个获得图例。所以我想如果你想走那条老路,你可以添加第二个图例作为手动注释。
  • Aes(..) 参数将变量链接到您在图中看到的内容。当您在每个 geom_ 上放置颜色时,您会将颜色与 aes() 中的变量名称相关联,在这种情况下是相同的。出于这个原因,我认为它们不能分开。

标签: r ggplot2 aes legend


【解决方案1】:

实际上,有一个比my previous hack 更好的选择——我敢肯定这在当时肯定已经存在,但我根本没有意识到这一点。使用ggnewscale 添加新比例非常容易。

据我所知,ggnewscale 目前是 CRAN 上唯一一个允许多个(离散的!)尺度以实现相同美学的软件包。对于连续刻度,现在还有ggh4x::scale_color/fill_multi。 GitHub 上还有 Claus Wilke 的 relayer 包。

我真的很喜欢 ggnewscale 包,因为它非常易于使用,并且几乎适用于所有美学。

ggplot(mapping = aes(x = load, y = feet)) +
  geom_line(data = dat, aes(color = mat, linetype = SF)) +
  scale_linetype(guide = FALSE) + # This is to delete the linetype legend
  ggnewscale::new_scale_color() +
  geom_path(data = soil, aes(x = load, y = feet, color = as.factor(test))) +
  scale_color_manual("Test", values = c('red','brown','green')) 

【讨论】:

    【解决方案2】:

    更新 - there is a much better option offered in this answer。我会留下这个,因为在某些情况下可能仍然需要使用虚假美学的黑客传说。

    正如@M-M 所说的那样——ggplot 不想为一种美学画两个图例。

    我真的希望您不会经常需要执行以下 hack 之类的操作:

    做一个假的审美(我选择了alpha),并手动定义每条线的颜色。 然后手动使用override.aes 更改您的图例键。

    如果您要显示的数据不止这些数据,请考虑使用不同的可视化/数据分离方式。 刻面是一件非常好的事情。

    library(ggplot2)
    library(dplyr)
    
    ggplot(dat, aes(x = load, y = feet)) +
      geom_line(aes(color = mat, linetype = SF)) +
      geom_path(dat = filter(soil,test ==1), 
                 aes(x = load, y = feet, alpha = factor(test)), color = 'red') +
      geom_path(dat = filter(soil,test ==2), 
                 aes(x = load, y = feet, alpha = factor(test)), color = 'brown') +
      geom_path(dat = filter(soil,test ==3), 
                 aes(x = load, y = feet, alpha = factor(test)), color = 'green') +
      scale_alpha_manual(values = c(rep(1,3))) +
      scale_linetype(guide = FALSE) +
      guides( alpha = guide_legend(title = 'test', 
                                   override.aes = list(color = c('red','brown','green'))))
    

    【讨论】:

    • 正如你提到的刻面,另一个黑客将包括两个刻面,删除它们之间的空间,相应地定义轴限制。总而言之,这不能以传统方式完成。干杯。 +1
    • 很棒的技巧。欣赏有关如何显示数据的建议。所有数据都需要在一个图表中。 “测试”是标准化测试的土壤强度,“垫”是使用不同垫配置的起重机地面载荷(虚线和实线之间的安全系数不同)。当“垫子”线穿过“测试”线时,这很糟糕……起重机翻倒了,刻面会混淆。客户根据线交叉选择垫子。从使用了 10 年的 Excel 图表转换而来。 SF 将显示在带有值的标题中。
    • @EricKrantz 那么请不要使用刻面,希望起重机不会倒下 :)
    【解决方案3】:

    或者你可以制作两个独立的ggplots,然后使用cowplot覆盖一个:

    library(cowplot) #cowplot_1.0.0
    library(ggplot2)
    
    myplot <- ggplot(dat, aes(x = load, y = feet)) +
               geom_line(aes(color = mat, linetype = SF)) +
               scale_linetype(guide = FALSE) + 
               lims(x = c(0,11), y = c(0,3)) + 
               theme(legend.justification = c(0, 1), # move the bottom legend up a bit
                     axis.text.x = element_blank(), # remove all the labels from the base plot
                     axis.text.y = element_blank(),
                     axis.title = element_blank())
    
    myplot2 <- ggplot() +  
                geom_path(dat = soil, aes(x = load, y = feet, color = factor(test))) + 
                theme_half_open() + 
                lims(x = c(0,11), y = c(0,3))
    
    aligned_plots <- align_plots(myplot, myplot2, align="hv", axis="tblr")
    
    ggdraw(aligned_plots[[1]]) + draw_plot(aligned_plots[[2]])
    

    【讨论】:

    • 谢谢!我尝试了cowplot,并且能够按照我的要求制作图表。但它为我的每个图例使用不同的字体大小,并用粗黑线作为轴标签和边框的主题。我确信有办法指定主题,使其更像默认的 ggplot...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多