使用R自定义ggplot图例

时间:2020-08-04 18:33:50

标签: r ggplot2 legend

我想在用ggplot制作的绘图中手动调整图例,并向图例中添加两个新项目。现在,图例显示为图例标题-factor(CruiseID),然后是带有文本201905的红色圆圈,然后是带有文本201906的蓝色圆圈,即使我在代码中有scale_fill_manual代码也是如此。
我想没有图例标题,其次是 红色圆圈和文字2019 MAB腿1, 蓝色圆圈和文字2019 MAB腿2, 灰框和文本Survey Domain 带黑色轮廓和文本访问区域的白框

示例数据

data<-data.frame(CruiseID=c(rep(201905,5),rep(201906,5)),
                 beglat=c(36.66,36.66,37.07,37.01,37.03,37.033,37.08,37.09,37.07,37.077),
                 beglong=c(-74.75,-74.75,-74.73,
                  -74.731,-74.90,-74.90,-74.88,-74.88,
                  -74.72,-74.72))


ggplot() +
  geom_point(data = data, aes(x = beglong, y = beglat,colour=factor(CruiseID))) +
  scale_colour_manual(values = c("red", "blue"),drop=T)+
  xlim(-76,-71)+
  ylim(36,42)+
  ggtitle("2019 MAB Survey Stations") +
  labs(x = "Longitude", y = "Latitude") +
  scale_fill_manual(values = c("red", "blue","gray87","black"),
                    labels = c('Leg 1', 'MAB Leg 2','Survey Domain','Access Area'))+
  theme_bw()+
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        plot.title=element_text(size=14),
        text=element_text(size=12),
        axis.text.x=element_text(colour="black", size = 12),
        axis.text.y=element_text(colour="black", size = 12),
        legend.justification=c(.5,.5), 
        legend.background = element_rect(fill = "white", color = NA),
        legend.position=c(0.8, 0.3),legend.box="vertical", 
        legend.margin=margin())

2 个答案:

答案 0 :(得分:2)

这是一个使用ggnewscale::new_scale_color为颜色创建两个比例的解决方案,一个用于点,另一个用于框。另外,我创建了一个名为df的附加data.frame,以使用geom_rect绘制2个矩形并为这些框创建图例。

library(ggplot2)
library(ggnewscale)

# Create another data frame to plot the rectangles and its legend
df <- data.frame (xmin = c(0,0),
            xmax = c(0,0),
            ymin = c(0,0),
            ymax = c(0,0),
            fill = c("A","B"))

ggplot() +
  geom_point(data = data, aes(x = beglong, 
                              y = beglat, 
                              colour=factor(CruiseID))) +
  # Move the color scale for the points before setting a new scale color
  scale_color_manual(values = c("red", "blue"),
                      labels = c('2019 MAB Leg 1', '2019 MAB Leg 2'))+
  # Set new scale color
  new_scale_color() +
  # plot rectangles in 0,0; where they will not appear in the plot's area
  geom_rect(data = df,aes(xmin = xmin,
                          xmax = xmax,
                          ymin = ymin,
                          ymax = ymax,
                          fill = fill,
                          col = fill)) +
  # Manually set color for the boxes
  scale_color_manual(values = c("white","black"),
                     labels = c('Survey Domain', 'Access Area')) +
  # Manually set fill for the boxes, use same labels as color so the box legends are combined
  scale_fill_manual(values = c("gray87","white"),
                    labels = c('Survey Domain', 'Access Area'))+
  xlim(-76,-71)+
  ylim(36,42)+
  ggtitle("2019 MAB Survey Stations") +
  labs(x = "Longitude", y = "Latitude") +
  theme_bw()+
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        plot.title=element_text(size=14),
        text=element_text(size=12),
        axis.text.x=element_text(colour="black", size = 12),
        axis.text.y=element_text(colour="black", size = 12),
        legend.justification=c(.5,.5),
        # Remove legend title
        legend.title = element_blank(),
        legend.background = element_rect(fill = "white", color = NA),
        legend.position=c(0.8, 0.3),legend.box="vertical", 
        legend.margin=margin())

desired plot

答案 1 :(得分:0)

首先,@ RuiBarradas对scale_fill_manual的评论是正确的,并且被您的代码误导了。我相信您将其包括在内,期望以后再添加您的区域(调查和访问权限)。也许您认为这可能会影响您的颜色图例(或只是将其弄糊涂)。无论如何,他的观点是正确的:scale_fill_manual不会执行任何操作,除非您实际将fill=用作情节中某处的aes主题。所有的命名等等都必须在scale_color_manual中为您的圆点进行。

此外,您有两个用于设置标签的选项。我相信您可以在规模调用中使用labels=来设置它们,而这可以是c("201905" = "MAB Leg 1", ...)的命名向量。或者,您可以在美学上最初使用标签(如下所述)。它们都可以工作,但是前者需要更多的数据管理而不需要ggplot。

我建议使用稍微不同的数据组织。

  • 由于您不想显示 201905(等)数字,但是要在其上分配标签和颜色,因此我将创建一个{{ 1}}框架将它们映射在一起,然后labels将它们放入。

  • 由于您没有merge尚未分配任何scale_fill_manual美观,因此我将创建一个伪造的fill=框架,其中包含您的两种类型的区域。我将为它们分配任意的areas值,以便我们仍然可以使用CruiseID框架来标识它们(以及它们的填充)。

labels

接下来,labels <- data.frame( CruiseID = c(201905, 201906, -1, -2), # 'factor' to preserve the order label = factor(c("MAB Leg 1", "MAB Leg 2", "Survey Domain", "Access Area")), color = c("red", "blue", "#00000000", "black"), fill = c("#00000000", "#00000000", "gray", "white") ) areas <- data.frame( label = c(-1, -2), beglat = NA_real_, beglong = NA_real_) 函数的values=值可以与命名向量一起使用。为此,我将使用scale_*_manual,使用一个小技巧将两列变成一个命名向量:

labels

要删除图例标题,只需将labels # CruiseID label color fill # 1 201905 MAB Leg 1 red #00000000 # 2 201906 MAB Leg 2 blue #00000000 # 3 -1 Survey Domain #00000000 gray # 4 -2 Access Area black white setNames(labels$color, labels$label) # MAB Leg 1 MAB Leg 2 Survey Domain Access Area # "red" "blue" "#00000000" "black" 添加到适用的name=NULL调用中即可。

代码:

scale_

updated ggplot2 with boxed legends

最后,如果不手动编辑grob(ggplot() + geom_point( # UPDATED data = merge(data, labels, by = "CruiseID", all.x = TRUE), aes(x = beglong, y = beglat, colour = label)) + scale_colour_manual( # UPDATED name = NULL, values = setNames(labels$color, labels$label), drop = TRUE) + geom_polygon( # NEW, placeholder data = merge(areas, labels, by = "CruiseID", all.x = TRUE), aes(x = beglong, y = beglat, fill = label), na.rm = TRUE) + scale_fill_manual( # UPDATED name = NULL, values = setNames(labels$fill, labels$label), drop = TRUE) + xlim(-76,-71) + ylim(36,42) + ggtitle("2019 MAB Survey Stations") + labs(x = "Longitude", y = "Latitude") + theme_bw() + theme( panel.grid.major = element_blank(), panel.grid.minor = element_blank(), plot.title=element_text(size=14), text=element_text(size=12), axis.text.x=element_text(colour="black", size = 12), axis.text.y=element_text(colour="black", size = 12), legend.justification=c(.5,.5), legend.background = element_rect(fill = "white", color = NA), legend.position=c(0.8, 0.3),legend.box="vertical", legend.margin=margin(), legend.key = element_rect(colour = "black") # NEW ) aphic gr ject)和/或图形表,我认为没有办法将一个图例的颜色装箱,而不是其他:主题选项ob使我们可以将它们装箱,但它适用于所有图例。如果您不介意点周围的框,那很好。如果没有它们,则可以删除legend.key选项,并将“访问区域”从白色更改为与背景颜色不同的颜色,以便可见。

legend.key=

updated ggplot2, not-boxed legend