ggplot2 - 拆分一个图例(两个色标)并删除另一个

ggplot2 - split one legend (two color scales) and delete another

我在 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,以及来自 soil data.frame 的 test(值 = 1、2、3)。

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

或者您可以制作两个单独的 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]])

更新 - 。我会留下这个,因为在某些情况下可能仍然需要具有虚假美学的黑客传奇。

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

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

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

如果要显示的数据不止这些数据,请考虑不同的可视化/数据分离方式。一个很好的事情是 facetting.

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'))))

其实还有比 - I am sure this must have been around back then, but I was simply not aware of it. Adding a new scale is very easy with 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'))