我创建了一个 map ,其中每个季度都有自己的图表. 这些柱状图共享一个传奇,因此我希望将一个传奇水平放置在 map 下方,我try 使用get_legend来做到这一点,但我不断收到警告,并且没有绘制任何传奇.

In get_plot_component(plot, "guide-box") :
 Multiple components found; returning the first one. To return all, use `return_all = TRUE`.'

因此,我提供了原始代码,希望有人能告诉我如何创建所需的情节. 此外,如果有人有关于如何gg保存最终对象的技巧,而每个子图的位置不会从R的新窗口中使用"zoom"打开图,那么这也会很有帮助.我总是必须调整宽度和高度才能重现这一点.

Here is what the map looks like now, in plot zoom: enter image description here

Here is the code to create it. I can't provide the original object because the dput() would be extremely long: enter image description here

# Reshape the data from wide to long format
quarts_long <- tidyr::pivot_longer(quarts, cols = c("Mammals", "Birds", "Amphibians", "Reptiles"), names_to = "Class", values_to = "Count")

# Calculate centroids of each quarter
quarts_centroids <- st_centroid(quarts)

# Create histograms for each quarter
hist_plots <- list()
for (i in 1:nrow(quarts)) {
  hist_plots[[i]] <- ggplot(quarts_long[quarts_long$Quarter == quarts$Quarter[i],]) +
    geom_col(aes(x = Class, y = Count, fill = Class)) +  
    scale_y_continuous(limits = c(0, 300), breaks = c(0, 150, 300)) +
    labs(y = "", x = "") +  # Remove axis labels
    theme_void() +  # Use minimal theme
    theme(axis.title.y = element_text(margin = margin(t = 0, r = 10, b = 0, l = 0)),  # Adjust y-axis label position
          axis.text.x = element_blank(),  # Remove x-axis text
          axis.text.y = element_text(size = 10),
          legend.position = "none")  # Adjust y-axis text size
}

# Create the quarters map
map_plot <- ggplot() +
  geom_sf(data = quarts, fill = alpha("white", 0)) +
  labs(x = NULL, y = NULL) +
  theme_void() +
  theme(legend.position = "none")  # Move legend to bottom

# Define shared legend
shared_legend <- get_legend(hist_plots[[1]])

# Draw the final plot with legend
p <- ggdraw() +
  draw_plot(hist_plots[[1]], 0.48, 0.63, 0.17, 0.15) +  # Draw the northeast
  draw_plot(hist_plots[[2]], 0.28, 0.63, 0.17, 0.15) +  # Draw the northwest
  draw_plot(hist_plots[[3]], 0.48, 0.38, 0.17, 0.15) +  # Draw the southeast
  draw_plot(hist_plots[[4]], 0.28, 0.38, 0.17, 0.15) +  # Draw the southwest
  draw_plot(map_plot, 0.05, 0.05, 0.95, 0.95)  + # Draw the quarters map
  draw_plot(shared_legend, 0.2, 0.05, 0.6, 0.1)

推荐答案

您至少有一个甚至可能有两个问题.首先,这里有一个更简单的reprex,它会产生同样的问题:

library(ggplot2)
library(cowplot)

p <- ggplot(mpg, aes(cty, hwy)) +
  geom_point(aes(color = drv)) +
  theme(legend.position = "none")

shared_legend <- get_legend(p)
#> Warning in get_plot_component(plot, "guide-box"): Multiple components found;
#> returning the first one. To return all, use `return_all = TRUE`.

ggdraw() +
  draw_plot(p, x = 0, width = .45) +
  draw_plot(p, x = .45, width = .45) +
  draw_plot(shared_legend, x = .85, width = .2)

1. Don't remove the legend before getting it

您的第一个问题是您在theme()中指定了legend.position = "none".这会删除该传奇,因此没有get_legend()可以"获取"的传奇."相反,从原始情节规范中删除legend.position = "none",然后添加after以获得传奇:

library(ggplot2)
library(cowplot)

p <- ggplot(mpg, aes(cty, hwy)) +
  geom_point(aes(color = drv))

shared_legend <- get_legend(p)
#> Warning in get_plot_component(plot, "guide-box"): Multiple components found;
#> returning the first one. To return all, use `return_all = TRUE`.

p <- p + theme(legend.position = "none")

ggdraw() +
  draw_plot(p, x = 0, width = .45) +
  draw_plot(p, x = .45, width = .45) +
  draw_plot(shared_legend, x = .85, width = .2)

2. Avoid get_legend() bug

只要legend.position = "right"(这是默认值),这就可以解决问题.但除此之外,get_legend()不会返回传奇,即known issue.

作为解决方案,您可以使用get_plot_component(plot, "guide-box", return_all = TRUE).您需要判断此内容以查看传奇位于什么位置,并相应地索引到结果中.例如,对于legend.position = "bottom":

p <- ggplot(mpg, aes(cty, hwy)) +
  geom_point(aes(color = drv)) +
  theme(legend.position = "bottom")

# when position = "bottom," legend is the third grob in the list
shared_legend <- cowplot::get_plot_component(p, "guide-box", return_all = TRUE)[[3]]

p <- p + theme(legend.position = "none")

ggdraw() +
  draw_plot(p, x = 0, y = .1, width = .5, height = .9) +
  draw_plot(p, x = .5, y = .1, width = .5, height = .9) +
  draw_plot(shared_legend, x = 0, y = 0, height = .2)

创建于2024-04-11,reprex v2.1.0

R相关问答推荐

将模拟变量乘以多个观测结果中的模拟变量

如何计算前一行的值,直到达到标准?

如何在RMarkdown LaTex PDF输出中包含英语和阿拉伯语?

在不安装软件包的情况下测试更新

在R中,如何在每个堆叠的条上放置误差条,特别是当使用facet_grid时?

如何改变时间图R中的悬停信息?

如何在区分不同条件的同时可视化跨时间的连续变量?

当我们有多个特殊字符时,使用gsub删除名称和代码'

在R中无法读入具有Readxl和lApply的数据集

标识R中多个列中缺少的唯一值

我如何才能找到FAMILY=POISSON(LINK=&Q;LOG&Q;)中的模型预测指定值的日期?

在ggplot2的框图中绘制所有级别的系数

在列表中排列R数据框中的列顺序

在R中使用列表(作为tibble列)进行向量化?

用多边形替换地块点

如何将图例文本添加到图例符号中

条形图中的条形图没有try 赋予它们的 colored颜色

使用列名和r中的前缀 Select 列的CREATE函数

如何为包创建自定义roxygen2标签?

如何在GGPlot中控制多个图例和线型