首页 > 解决方案 > R - 如何在我的 ggplot2 图表中添加双变量图例?

问题描述

我正在尝试在我的ggplot2图表中添加一个双变量图例,但我不知道(a)这是否可以通过一些guides选项以及(b)如何实现。

我设法产生接近预期结果的唯一方法是专门创建一个类似于图例的新图表(p.legend如下命名)并通过cowplot包将其插入原始图表中的某个位置(p.chart如下命名)。但是肯定有比这更好的方法,因为这种方法首先需要创建图例并调整其大小/位置以使其适合原始图表。

这是我的方法的一个虚拟示例的代码:

library(tidyverse)

# Create Dummy Data #
set.seed(876)
n <- 2
df <- expand.grid(Area = LETTERS[1:n],
                  Period = c("Summer", "Winter"),
                  stringsAsFactors = FALSE) %>% 
      mutate(Objective = runif(2 * n, min = 0, max = 2),
             Performance = runif(2 * n) * Objective) %>% 
      gather(Type, Value, Objective:Performance)

# Original chart without legend #
p.chart <- df %>% 
            ggplot(., aes(x = Area)) + 
              geom_col(data = . %>% filter(Type == "Objective"),
                       aes(y = Value, fill = Period),
                       position = "dodge", width = 0.7, alpha = 0.6) + 
              geom_col(data = . %>% filter(Type == "Performance"),
                       aes(y = Value, fill = Period),
                       position = "dodge", width = 0.7) + 
              scale_fill_manual(values = c("Summer" = "#ff7f00", "Winter" = "#1f78b4"), guide = FALSE) + 
              theme_minimal() + 
              theme(panel.grid.major.x = element_blank(),
                    panel.grid.minor.y = element_blank())

# Create a chart resembling a legend #
p.legend <- expand.grid(Period = c("Summer", "Winter"),
                        Type   = c("Objective", "Performance"),
                        stringsAsFactors = FALSE) %>% 
              ggplot(., aes(x = Period, y = factor(Type, levels = c("Performance", "Objective")),
                                                   fill = Period, alpha = Type)) + 
                geom_tile() + 
                scale_fill_manual(values = c("Summer" = "#ff7f00", "Winter" = "#1f78b4"), guide = FALSE) + 
                scale_alpha_manual(values = c("Objective" = 0.7, "Performance" = 1), guide = FALSE) + 
                ggtitle("Legend") + 
                theme_minimal() + 
                theme(plot.title = element_text(hjust = 0.5),
                      rect = element_rect(fill = "transparent"),
                      axis.title = element_blank(),
                      panel.grid.major = element_blank())

# Add legend to original chart #
p.final <- cowplot::ggdraw() + 
                  cowplot::draw_plot(plot = p.chart) + 
                  cowplot::draw_plot(plot = p.legend, x = 0.5, y = 0.65, width = 0.4, height = 0.28, scale = 0.7)

# Save chart #
cowplot::ggsave("Bivariate Legend.png", p.final, width = 8, height = 6, dpi = 500)

...以及生成的图表: 带有双变量图例的图表

有没有更简单的方法来做到这一点?

标签: rggplot2legend

解决方案


这可能在某些时候有效,但现在颜色框似乎忽略了所有中断、名称和标签(@ClausWilke?)。可能是因为该multiscales软件包处于非常早期的阶段。

发布,因为当未来的读者在这里时它可能会起作用。

library(multiscales)

df %>% 
  mutate(
    period = as.numeric(factor(Period)),
    type = as.numeric(factor(Type))
  ) %>% 
  ggplot(., aes(x = Area, y = Value, fill = zip(period, type), group = interaction(Area, Period))) + 
  geom_col(width = 0.7, position = 'dodge') + 
  bivariate_scale(
    "fill", 
    pal_hue_sat(c(0.07, 0.6), c(0.4, 0.8)),
    guide = guide_colorbox(
      nbin = 2, 
      name = c("Period", "Type"),                       #ignored
      breaks = list(1:2, 1:2),                          #ignored
      labels = list(levels(.$Period), levels(.$Type))   #ignored
  )

在此处输入图像描述


推荐阅读