R-如何在我的ggplot2图表中添加双变量图例?

时间:2018-07-12 06:15:06

标签: r ggplot2 legend

我正在尝试向我的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)

...以及结果图表: Chart with Bivariate Legend

有没有更简单的方法?

1 个答案:

答案 0 :(得分:1)

这可能在某些时候可行,但是现在,颜色框似乎忽略了所有的中断,名称和标签(@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
  )

enter image description here