使用"颜色"和"填充"作为美学元素,在ggplot中将不同类型的图例合并在一起。

3

我在使用ggplot绘图中遇到了一个问题,无法正确绘制图例。我已经在互联网上搜索了很久,但仍未找到解决方案。

我试图创建一个包含不同线条和多边形shapefile的ggplot。我使用函数geom_sf()绘制shapefile,绘制本身并没有问题。我的问题与图例创建有关。

目标是创建一个具有单个图例的绘图,并且将所有不同的shapefile类型以及它们的颜色或填充美学都包括在内。也就是说,线形状应该在图例中表示为简单的线条,而多边形形状应该在图例中表示为简单的多边形。我已经成功地完成了所有这些操作。

主要困难在于其中一个多边形形状(为了更好的可读性)不仅使用“fill”参数作为美学效果,而且还使用“color”参数。

如果我创建一个绘图,在该绘图中,所有polygonshapes始终使用fill参数作为美学效果,所有lineshapes始终使用color参数作为美学效果,则一切正常。但是一旦我在绘图中包含同时使用两个参数的polygonshape,它将破坏整个图例结构。在这种情况下,例如,用于线形shapefile的符号突然具有框架和/或背景,尽管它们不应该有这些。

使用ggplot无法构建这样的内容吗?还是我只是笨手笨脚?

总结:

类似于下面创建的最小示例,我想在此绘图中创建一个单个图例,其中:

  • A = 没有边框的多边形符号(如图所示)
  • B = 具有边框的多边形符号(如图所示),以及
  • C = 没有边框或背景的简单线条(如图所示)。

我该怎么做才能实现这个目标?

library(ggplot2)
library(sf)

poly1 <- cbind(lon = c(5, 6, 7, 5), lat = c(52, 53, 51, 52))
poly2 <- cbind(lon = c(3, 5, 7, 3), lat = c(50, 52, 50, 50))

poly1 <- st_sf(st_sfc(st_polygon(list(poly1))))
poly2 <- st_sf(st_sfc(st_polygon(list(poly2))))
line <- st_sf(st_sfc(list(st_linestring(cbind(lon = c(5.5, 4.5), lat = c(53.5, 54.5))))))

ggplot() +
  geom_sf(data = poly1, 
          aes(fill = "A"),
          colour = NA,
          show.legend = "polygon") +
  geom_sf(data = poly2, 
          aes(fill = "B", 
              colour = "B"),
          show.legend = "polygon") +
  geom_sf(data = line, 
          aes(colour = "C"), 
          show.legend = "line") +
  scale_fill_manual(name="Legend", 
                    values = c("A" = "yellow", "B" = "green"), 
                    guide = guide_legend(override.aes = list(linetype = c("blank","blank"), shape = NA))
                    ) +
  scale_colour_manual(name="Legend",values = c("B" = "blue", "C" = "purple"),
                     guide = guide_legend(override.aes = list(linetype = c(0, 1)))) +
  theme_bw()
2个回答

1
我也喜欢@AllanCameron的答案,但是这里有一种不使用ggnewscale实现相同效果的方法。
您总共有三个键。对于AB,这两者都应该表示为多边形,但是B应该有一个边框,而A则没有。由于C应该在图例中用单独的符号表示,所以它是与众不同的。
因此,在这里的方法是让AB属于同一个图例(从color=fill=组合),并将C保留到单独的图例中。
对于AB,我在两者上都在aes()中指定了fill=color=,然后使用scale_*_manual()函数为两者计算颜色。
如果在aes()中将color=赋给C,你会强制ggplot2将它与AB一起推到图例中。这意味着我们需要在不同的美学下指定C的图例!在这种情况下,我使用了alpha=,但是linetypesize等也可以使用相同的方法。
p <-
ggplot() +
  geom_sf(
    data = poly1, aes(fill = "A", colour = "A")) +
  geom_sf(
    data = poly2, aes(fill = "B", colour = "B")) +
  geom_sf(
    data = line, aes(alpha = "C"), colour = "purple") +
  
  scale_fill_manual(
    name="Legend", values = c("A" = "yellow", "B" = "green")) +
  scale_colour_manual(
    name="Legend", values = c("A" = "transparent", "B" = "blue", "C" = "purple")) +
  scale_alpha_manual(name=NULL, values=1) +

  guides(
    fill=guide_legend(order=1, override.aes = list(linetype = c(0,1))),
    colour= "none"
  ) +
  
  theme_bw()
p

enter image description here

为了让图例更加接近,您可以通过theme()指定legend.spacing。 您需要尝试不同的数字,但它是有效的。 在这种情况下,重要的是将legend.background也设置为透明,因为图例会相互裁剪。
p + theme(
  legend.background = element_rect(fill=NA),
  legend.spacing = unit(-15, "pt")
  )

enter image description here


1
您可以使用ggnewscale并为每个几何层设置关键字形状来实现此操作:
ggplot() +
  geom_sf(data = poly1, 
          aes(fill = "A"),
          colour = NA,
          key_glyph = "rect") +
  scale_fill_manual(values = "yellow", name = NULL, 
                      guide = guide_legend(order = 1)) +
  ggnewscale::new_scale_fill() +
  ggnewscale::new_scale_color() +
  geom_sf(data = poly2, 
          aes(fill = "B", 
              colour = "B"),
          key_glyph = "polygon") +
  scale_color_manual(values = "blue", name = NULL, 
                      guide = guide_legend(order = 2)) +
  scale_fill_manual(values = "green", name = NULL, 
                      guide = guide_legend(order = 2)) +
  ggnewscale::new_scale_color() +
  geom_sf(data = line, 
          aes(colour = "C"), 
          key_glyph = "path") +
  scale_colour_manual(values = "purple", name = NULL, 
                      guide = guide_legend(order = 3)) +
  theme_bw()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接