ggplot - Расположение нескольких легенд

Я хочу организовать несколько легенд в ggplot с несколькими строками и столбцами. Однако в настоящее время из документации я могу выбирать только направление или управлять строками / столбцами в пределах одной легенды. Я что-то упускаю? Спасибо за любую ссылку на решение. Вот пример кода, то, что я сделал, и ожидаемый результат.

data <- seq(1000, 4000, by=1000)
colorScales <- c("#c43b3b", "#80c43b", "#3bc4c4", "#7f3bc4")
names(colorScales) <- data
ggplot() +
    geom_point(aes(x=data, y=data, color=as.character(data), fill=data, size=data),
               shape=21) +
    scale_color_manual(name="Legend 1",
                      values=colorScales) +
    scale_fill_gradientn(name="Legend 2",
                          labels=comma, limits=c(0, max(data)),
                          colours=rev(c("#000000", "#FFFFFF", "#BA0000")),
                         values=c(0, 0.5, 1)) +
    scale_size_continuous(name="Legend 3") +
    theme(legend.direction = "vertical", legend.box = "vertical")

Вертикальная легенда вывода:  введите описание изображения здесь

ggplot() +
    geom_point(aes(x=data, y=data, color=as.character(data), fill=data, size=data),
               shape=21) +
    scale_color_manual(name="Legend 1",
                       values=colorScales) +
    scale_fill_gradientn(name="Legend 2",
                         labels=comma, limits=c(0, max(data)),
                         colours=rev(c("#000000", "#FFFFFF", "#BA0000")), 
                         values=c(0, 0.5, 1)) +
    scale_size_continuous(name="Legend 3") +
    theme(legend.direction = "vertical", legend.box = "horizontal")

Вывести горизонтальную легенду  введите здесь описание изображения

ggplot() +
    geom_point(aes(x=data, y=data, color=as.character(data), fill=data, size=data),
               shape=21) +
    scale_color_manual(name="Legend 1",
                       values=colorScales) +
    scale_fill_gradientn(name="Legend 2",
                         labels=comma, limits=c(0, max(data)),
                         colours=rev(c("#000000", "#FFFFFF", "#BA0000")), 
                         values=c(0, 0.5, 1)) +
    guides(colour = guide_legend(nrow = 2, byrow = T, override.aes=list(size=4))) +
    guides(size = guide_legend(nrow = 2, byrow = T)) +
    scale_size_continuous(name="Legend 3") +
    theme(legend.direction = "vertical", legend.box = "vertical")

Легенда вывода с вертикальным расположением, по 2 столбца в каждой легенде:  введите описание изображения здесь

Я хочу вот что:

введите описание изображения здесь


person Sinh Nguyen    schedule 28.08.2018    source источник
comment
Кстати, рассматривали ли вы возможность использования plotly - я считаю, что у него больше возможностей для размещения элементов.   -  person Gautam    schedule 28.08.2018
comment
Обходной путь может состоять в том, чтобы построить 3 отдельных графика, извлечь их легенды, а затем использовать cowplot::plot_grid, чтобы объединить их определенным образом cran.r-project.org/web/packages/cowplot/vignettes/   -  person Tung    schedule 28.08.2018
comment
Вы не можете делать то, что хотите, с ggplot2 из коробки, т.е. я почти уверен, что вы ничего не пропустили. Вы можете вручную создать другие аранжировки, если не против возиться, например, с cowplot::get_legend и cowplot::plot_grid.   -  person Axeman    schedule 28.08.2018
comment
gtable::gtable_filter также позволяет извлекать легенды, которые затем можно размещать в любом месте на графиках, используя gridExtra::annotation_custom, Подробности здесь   -  person Jan Boyer    schedule 28.08.2018


Ответы (1)


Идея состоит в том, чтобы создать каждый сюжет индивидуально (color, fill & size), затем извлечь их легенды и объединить их желаемым образом вместе с основным сюжетом.

Подробнее о пакете cowplot см. здесь и patchwork пакете здесь

library(ggplot2)
library(cowplot)   # get_legend() & plot_grid() functions
library(patchwork) # blank plot: plot_spacer()

data <- seq(1000, 4000, by = 1000)
colorScales <- c("#c43b3b", "#80c43b", "#3bc4c4", "#7f3bc4")
names(colorScales) <- data

# Original plot without legend
p0 <- ggplot() +
  geom_point(aes(x = data, y = data, 
                 color = as.character(data), fill = data, size = data),
             shape = 21
  ) +
  scale_color_manual(
    name = "Legend 1",
    values = colorScales
  ) +
  scale_fill_gradientn(
    name = "Legend 2",
    limits = c(0, max(data)),
    colours = rev(c("#000000", "#FFFFFF", "#BA0000")),
    values = c(0, 0.5, 1)
  ) +
  scale_size_continuous(name = "Legend 3") +
  theme(legend.direction = "vertical", legend.box = "horizontal") +
  theme(legend.position = "none")

# color only
p1 <- ggplot() +
  geom_point(aes(x = data, y = data, color = as.character(data)),
             shape = 21
  ) +
  scale_color_manual(
    name = "Legend 1",
    values = colorScales
  ) +
  theme(legend.direction = "vertical", legend.box = "vertical")

# fill only
p2 <- ggplot() +
  geom_point(aes(x = data, y = data, fill = data),
             shape = 21
  ) +
  scale_fill_gradientn(
    name = "Legend 2",
    limits = c(0, max(data)),
    colours = rev(c("#000000", "#FFFFFF", "#BA0000")),
    values = c(0, 0.5, 1)
  ) +
  theme(legend.direction = "vertical", legend.box = "vertical")

# size only
p3 <- ggplot() +
  geom_point(aes(x = data, y = data, size = data),
             shape = 21
  ) +
  scale_size_continuous(name = "Legend 3") +
  theme(legend.direction = "vertical", legend.box = "vertical")

Получить все легенды

leg1 <- get_legend(p1)
leg2 <- get_legend(p2)
leg3 <- get_legend(p3)

# create a blank plot for legend alignment 
blank_p <- plot_spacer() + theme_void()

Объедините легенды

# combine legend 1 & 2
leg12 <- plot_grid(leg1, leg2,
                   blank_p,
                   nrow = 3
)

# combine legend 3 & blank plot
leg30 <- plot_grid(leg3, blank_p,
                   blank_p, 
                   nrow = 3
)

# combine all legends
leg123 <- plot_grid(leg12, leg30,
                    ncol = 2
)

Собери все вместе

final_p <- plot_grid(p0,
                     leg123,
                     nrow = 1,
                     align = "h",
                     axis = "t",
                     rel_widths = c(1, 0.3)
)

print(final_p)

Создано 28 августа 2018 г. пакетом REPEX (v0.2.0.9000).

person Tung    schedule 29.08.2018
comment
Как бы вы поместили легенду внизу, а другую - справа? - person Alvaro Morales; 14.07.2021
comment
Можете ли вы вручную нарисовать то, что вы имели в виду? - person Tung; 14.07.2021
comment
Я уже спрашивал: stackoverflow.com/questions/68369581/ - person Alvaro Morales; 14.07.2021