为什么用 ggplot 绘制 geom_sf 时我的图例没有出现?

Why doesn't my legend appear when drawing geom_sf with ggplot?

我正在跟随 this guide 在地图上创建一些点。一切都很好,但我无法为这些点制作图例。我只是要复制代码以获得 MWE(但所有功劳都归功于 Valentin Stefan):

library(rgeos)
library(sf)
library(rnaturalearth)
library(rnaturalearthdata)
library(dplyr)
library(ggplot2)
library(ggrepel)

theme_set(
  theme_bw() +
    theme(panel.background = element_rect(fill = "azure"),
          panel.grid.major = element_blank(),
          axis.title = element_blank(),
          axis.text = element_text(size = 8))
)

world <- rnaturalearth::ne_countries(scale = 'medium', returnclass = "sp")
box_cut <- bbox2SP(n = 90, s = -90, w = -70, e = 120, proj4string = world@proj4string)
world_crop <- gDifference(world, box_cut)

pacific_crop <- world_crop %>% 
  st_as_sf() %>% # change from sp to sf object/class
  st_shift_longitude() %>% 
  st_crop(c(xmin = st_bbox(.)[["xmin"]],
            xmax = st_bbox(.)[["xmax"]],
            ymin = -50,
            ymax = 30))

ggplot() +
  geom_sf(data = pacific_crop)

tiny_countries <- rnaturalearthdata::tiny_countries50 %>% 
  st_as_sf() %>%
  st_shift_longitude() %>% 
  st_crop(c(xmin = 120, xmax = 250, ymin = -50, ymax = 30)) %>% 
  # Also adds the coordinates to be used for labeling with geom_text_repel
  bind_cols(st_coordinates(.) %>% as.data.frame())

rbPal <- colorRampPalette(c('red','blue'))

Col <- rbPal(18)

ggplot() +
  geom_sf(data = pacific_crop) +
  geom_sf(data = tiny_countries, size = 2, color = Col, show.legend = "point")

如何获得颜色图例?

我尝试过更改图例的位置,但没有成功:

theme(legend.position = c(.5,.5))

当数据集中的一列或多列通过 aes() 映射到审美修饰符之一(例如,fillshapesizecoloralpha...)。在您的绘图代码中,您指定了一个颜色值列表,但是 ggplot2 不知道在您的数据中应该 link 编辑什么。因此,颜色是根据数据框 tiny_countries 中的观察值逐行映射的,实际上不会在数据和颜色之间生成 link。

当您将 color 放在 aes() 中时,表示此修饰符应映射到数据中的特定列。 ggplot2 然后将为数据框中的每个“不同”值分配颜色。如果您只想 ggplot2 指定每个小国家的颜色不同,那么,您需要为每个国家选择一个标签。我们自然希望标签与名称相对应,因为...这是有道理的,所以我们将通过 aes(color=name).

创建映射

请注意这并没有指定颜色。默认情况下,ggplot2 将使用它的默认着色方案,但由于您已经为颜色指定了适当数量的值列表...我们可以告诉 ggplot2 我们想要覆盖默认着色和手动使用您自己的特定颜色。我们使用 scale_*_manual() 函数来做到这一点,其中 * 对应于所讨论的特定审美修饰符。把这些放在一起你会得到这个:

ggplot() +
  geom_sf(data = pacific_crop) +
  geom_sf(data = tiny_countries, aes(color=name), size = 2, show.legend = "point") +
  scale_color_manual(values=Col) +
  theme(legend.position='bottom')  # thought the legend looks best on the bottom