如何 "group" ggplot 中的图例

How to "group" a legend in ggplot

我正在尝试完善这个情节。

  1. 我想得到一个自定义的图例,其中与相同颜色相关联的国家在同一类别中(而不是一遍又一遍地重复相同的颜色框) 理想情况下,我想要

-5:[红框] 值为 -5

的国家/地区列表

-4:[浅红色方框] 值为 -4

的国家/地区列表

等等

  1. 俄罗斯在右上角被切了...我如何扩大这个情节的范围以覆盖它? 太感谢了! 这是我的代码:
library(RColorBrewer)
library(maptools)
library(ggplot2)
library(tidyverse)
if (!require(gpclib)) install.packages("gpclib", type="source")
gpclibPermit()

data(wrld_simpl)

ddf <- read.table(text="
                 country value
                 'Argentina' 2
                 'Australia' 3
                 'Belgium' 5
                 'Brazil' 17
                 'Canada' 2
                 'China' -2
                 'France' 7
                 'Germany' 97
                 'Indonesia' -2
                 'Italy' 9
                 'Japan' 9
                 'Portugal' -2
                 'Russia' 3
                 'Saudi Arabia' 2
                 'Singapore' -5
                 'Slovenia' 1
                 'Spain' -3
                 'Switzerland' 0
                 'Turkey' 0
                 'United States' 18", header=TRUE)

ddf$color <- case_when(ddf$value==1 ~ "#66FFFF",
                   ddf$value==2 ~ "#3399CC",
                   ddf$value==3 ~ "#0066CC",
                   ddf$value==4 ~ "#3333FF",
                   ddf$value>=5 ~ "#000066",
                   ddf$value==0 ~ "#FFCC66",
                   ddf$value==-1 ~ "FF9900",
                   ddf$value==-2 ~ "#FF6600",
                   ddf$value==-3 ~ "#FF0000",
                   ddf$value==-4 ~ "#CC0000",
                   ddf$value<=-5 ~ "#990000")

plotme <- function() {
  
  # this lets us use the contry name vs 3-letter ISO
  wrld_simpl@data$id <- wrld_simpl@data$NAME
  
  wrld <- fortify(wrld_simpl, region="id")
  wrld <- subset(wrld, id != "Antarctica") # we don't rly need Antarctica
  
  gg <- ggplot()
  
  # setup base map
  gg <- gg + geom_map(data=wrld, map=wrld, aes(map_id=id, x=long, y=lat), fill="white", color="#7f7f7f", size=0.15)
  
  # add our colored regions
  gg <- gg + geom_map(data=ddf, map=wrld, aes(map_id=country, fill=country),  color="#7f7f7f", size=0.15)
  
  # this sets the scale and, hence, the legend
  gg <- gg + scale_fill_manual(values=ddf$color, 
                               name="Interactions")
  
  # this gives us proper coords. mercator proj is default
  gg <- gg + coord_map()
  gg <- gg + labs(x="", y="")
  gg <- gg + theme(plot.background = element_rect(fill = "transparent", colour = NA),
                   panel.border = element_blank(),
                   panel.background = element_rect(fill = "transparent", colour = NA),
                   panel.grid = element_blank(),
                   axis.text = element_blank(),
                   axis.ticks = element_blank(),
                   legend.position = "bottom")
  gg

}

plotme()

这是我的情节:

enter image description here

也许这会让您更接近您想要实现的目标:

  1. 因为在填充美学上每个类别地图只需要一个图例键 value 而不是 country。为此,我首先重新编码 value,以便将大于 5 的值设置为等于 5。

  2. 为了获得正确的颜色,我使用 scale_fill_manual 和我通过 tibble::deframe 从你的 df ddf 中提取的命名颜色矢量。

  3. 对于标签,您可以按类别粘贴国家/地区标签,我通过 group_bysummarize 这样做。另外我添加了 value。总结之后,我再次通过 tibble::deframe.

    将标签提取为命名向量
  4. 最后我使用 guide_legend 来设计图例的样式,例如我将图例标题放在顶部,将图例标签放在按键下方。

library(RColorBrewer)
library(maptools)
library(tidyverse)

ddf <- ddf %>%
  mutate(value = ifelse(value > 5, 5, value))

# Vector of labels
labels <- ddf %>%
  group_by(value) %>%
  arrange(country) %>%
  summarise(label = paste(country, collapse = "\n")) %>%
  ungroup() %>%
  mutate(label = paste(value, label, sep = ":\n")) %>%
  deframe()

# Vector of colors
cols <- ddf %>%
  distinct(value, color) %>%
  deframe()

# Get maximum length of country label to set width of legend
max_len_country <- max(strwidth(ddf$country, units = "inches"))

ggplot() +
  geom_map(data = wrld, map = wrld, aes(map_id = id, x = long, y = lat), fill = "white", color = "#7f7f7f", size = 0.15) +
  geom_map(data = ddf, map = wrld, aes(map_id = country, fill = factor(value)), color = "#7f7f7f", size = 0.15) +
  scale_fill_manual(
    values = cols, labels = labels, name = "Interactions",
    guide = guide_legend(label.position = "bottom", title.position = "top", keywidth = unit(max_len_country, "inches"), byrow = TRUE, nrow = 1)
  ) +
  coord_map() +
  labs(x = "", y = "") +
  theme(
    plot.background = element_rect(fill = "transparent", colour = NA),
    panel.border = element_blank(),
    panel.background = element_rect(fill = "transparent", colour = NA),
    panel.grid = element_blank(),
    axis.text = element_blank(),
    axis.ticks = element_blank(),
    legend.position = "bottom"
  )
#> Warning: Ignoring unknown aesthetics: x, y