Смешайте цвет, заливку и тип линии в легенде R ggplot

#r #ggplot2 #legend #sf

Вопрос:

У меня есть карта, на которой я пытаюсь добавить в легенду 2 заполненных полигона и 1 полигон, но только с очерченным контуром (который будет представлен только пунктирной линией).

 library(sf);library(ggplot)
# point
p <- rbind(c(1,2), c(2,1), c(3,2), c(3.5,3.5), c(3.4,3.6), c(3.9,1.4))
(mp <- st_multipoint(p))

p1 <- rbind(c(0,0), c(1,0), c(3,2), c(2,4), c(1,4), c(0,0))
p2 <- rbind(c(1,1), c(1,2), c(2,2), c(1,1))
pol <-st_polygon(list(p1,p2))

p3 <- rbind(c(3,0), c(4,0), c(4,1), c(3,1), c(3,0))
p4 <- rbind(c(3.3,0.3), c(3.8,0.3), c(3.8,0.8), c(3.3,0.8), c(3.3,0.3))[5:1,]
p5 <- rbind(c(3,3), c(4,2), c(4,3), c(3,3))
(mpol1 <- st_multipolygon(list(list(p3))))
(mpol2 <- st_multipolygon(list(list(p4))))
(mpol3 <- st_multipolygon(list(list(p5))))

ggplot(mp, aes(geometry = geometry))   
  geom_sf(data = pol, aes(geometry = geometry), inherit.aes = FALSE)  
  # Add the points 
  geom_sf(data = mpol1, alpha = 0.5, aes(geometry = geometry, colour = "grey90", fill  = "grey90"), size = 0.05)   
  geom_sf(data = mpol2,   alpha = 0.5, aes(geometry = geometry, colour = "grey20", fill  = "grey20"), size = 0.05)  
  geom_sf(data = mpol3, alpha = 0.5, aes(geometry = geometry,colour = "grey30", fill=NA), size = 0.8, linetype = "dotted")  
  scale_color_manual(values = c(alpha("grey90",.5),alpha("grey20",.5),alpha("grey30",.5)), labels = c("item1", "item2","item3"), name="My Leg. hurts")  
  scale_fill_manual( values = c(alpha("grey90",.5),alpha("grey20",.5),NA), labels = c("item1", "item2","item3"), name="My Leg. hurts")   
  theme_bw() 
  theme(legend.key = element_rect(fill = NA), 
        legend.background = element_rect(fill = NA),
        legend.text = element_text(size = 12), 
        legend.title = element_text(size = 12,face='bold'))
 

Дает

введите описание изображения здесь

Но я хочу этого:

введите описание изображения здесь

Как этого можно достичь?

Ответ №1:

Чтобы немного подробнее остановиться на более раннем ответе Яна Кэмпбелла:

Рассмотрим этот код (мое единственное дополнение- show.legend = 'line' в последнем geom_sf() вызове).

 ggplot(mp, aes(geometry = geometry))   
  geom_sf(data = pol, aes(geometry = geometry), inherit.aes = FALSE)  
  # Add the points 
  geom_sf(data = mpol1, alpha = 0.5, aes(geometry = geometry, colour = "grey90", fill  = "grey90"), size = 0.05)   
  geom_sf(data = mpol2,   alpha = 0.5, aes(geometry = geometry, colour = "grey20", fill  = "grey20"), size = 0.05)  
  geom_sf(data = mpol3, alpha = 0.5, aes(geometry = geometry,colour = "grey30", fill=NA), size = 0.8, linetype = "dotted", show.legend = 'line')  
  scale_color_manual(values = c(alpha("grey90",.5),alpha("grey20",.5),alpha("grey30",.5)), labels = c("item1", "item2","item3"))  
  scale_fill_manual( values = c(alpha("grey90",.5),alpha("grey20",.5),NA), labels = c("item1", "item2","item3"), guide = FALSE)   
  theme_bw()  
  theme(legend.key = element_rect(fill = NA), 
        legend.background = element_rect(fill = NA),
        legend.text = element_text(size = 12), 
        legend.title = element_text(size = 12,face='bold'))  
  guides(color = guide_legend(override.aes = 
                                list(color=c(NA,NA,"grey20"), 
                                     fill=c("grey90","grey20","white"),
                                     linetype = c("dotted"))))  
  labs(color = "My Leg. hurts")
 

у меня болит нога / диаграмма

Комментарии:

1. Я использовал show.legend = 'none' его раньше, но не думал, что ты можешь это сделать. Аккуратный.

2. Спасибо! Иногда это необходимо — один и тот же вызов geom_sf() может означать разные вещи в разных контекстах (точки, линии, полигоны), и иногда вам нужно немного настроить легенду…

3. Да! И можете ли вы изменить outline пункт 3 так, чтобы вы просто видели пунктирную линию?

4. По какой-то причине theme(legend.key = element_rect(fill = NA, color = NA)) не работает

5. @M. Босолей, боюсь, я не знаю, как с этим справиться 🙁 вы можете удалить linetype = c("dotted") из переопределения.aes в своем вызове руководства, что сделает его немного более приемлемым, но тонкая линия вокруг поля останется. Я не мог избавиться от этого, когда пытался

Ответ №2:

Это не совсем то, что вы просили, но это очень близко. Вы можете использовать override.aes аргумент guides :

 ggplot(mp, aes(geometry = geometry))   
  geom_sf(data = pol, aes(geometry = geometry), inherit.aes = FALSE)  
  # Add the points 
  geom_sf(data = mpol1, alpha = 0.5, aes(geometry = geometry, colour = "grey90", fill  = "grey90"), size = 0.05)   
  geom_sf(data = mpol2,   alpha = 0.5, aes(geometry = geometry, colour = "grey20", fill  = "grey20"), size = 0.05)  
  geom_sf(data = mpol3, alpha = 0.5, aes(geometry = geometry,colour = "grey30", fill=NA), size = 0.8, linetype = "dotted")  
  scale_color_manual(values = c(alpha("grey90",.5),alpha("grey20",.5),alpha("grey30",.5)), labels = c("item1", "item2","item3"))  
  scale_fill_manual( values = c(alpha("grey90",.5),alpha("grey20",.5),NA), labels = c("item1", "item2","item3"), guide = FALSE)   
  theme_bw()  
  theme(legend.key = element_rect(fill = NA), 
        legend.background = element_rect(fill = NA),
        legend.text = element_text(size = 12), 
        legend.title = element_text(size = 12,face='bold'))  
  guides(color = guide_legend(override.aes = 
                                list(color=c(NA,NA,"grey20"), 
                                     fill=c("grey90","grey20","white"),
                                     linetype = c("dotted"))))  
  labs(color = "My Leg. hurts")
 

введите описание изображения здесь

К сожалению, я не вижу хорошего способа изменить альфа как заливки, так и цвета в легенде.