Home > Enterprise >  Changing legend for geom_rect to show line types
Changing legend for geom_rect to show line types

Time:10-05

Dear R and ggplot users

I want to plot a map with some groups of rectangles inside. Each group has to be drawn with a different line type and a group has to be filled. I get the map with this code

library("tidyverse")
library("ggplot2")
library("sf")
library("rnaturalearth")
library("rnaturalearthdata")
    
world <- ne_countries(scale = "medium", returnclass = "sf")

x1.SST <- c(-2,0,0,-2)
x2.SST <- c(5,10,13,15)
y1.SST <- c(37,40,36,35)
y2.SST <- c(41,45,45,45)

x1.WV <- c(1,2.5,-3)
x2.WV <- c(5,8,10.25)
y1.WV <- c(37.5,39.5,35)
y2.WV <- c(40.5,43.75,45)

x1.CM <- c(2,1,8)
x2.CM <- c(3.5,3.5,14)
y1.CM <- c(39,41,45.5)
y2.CM <- c(40,44,47.5)

d.SST <- data.frame(x1=x1.SST, x2=x2.SST, y1=y1.SST, y2=y2.SST,
                SST=c('MALL SST','AUD SST','VAIA SST','WMED'), r=c(1,2,3,4))
d.WV <- data.frame(x1=x1.WV, x2=x2.WV, y1=y1.WV, y2=y2.WV,
                        WV=c('MALL WV','AUD WV','VAIA WV'), r=c(1,2,3))
d.CM <- data.frame(x1=x1.CM, x2=x2.CM, y1=y1.CM, y2=y2.CM,
                   CM=c('MALL CM','AUD CM','VAIA CM'), r=c(1,2,3))

ggplot(data = world)   geom_sf(fill = "lavender")   
coord_sf(xlim = c(-5, 16), ylim = c(34,48))   xlab("")   ylab("") 
geom_rect(data=d.SST, mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2, colour=SST), fill=NA, alpha=0.5, size=1)   
geom_rect(data=d.WV, mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2, colour=WV), fill=NA, alpha=0.5, size=1, linetype = 2)   
geom_rect(data=d.CM, mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2, colour=CM), fill="blue", alpha=0.2, size=0.5, linetype = 1)   
theme_light()     

with this result enter image description here

What I need now is to split the legend into three different parts for SST, WV and CM and to show the linetype for the non filled rectangles. Seen and tried scale_fill_manual and scale_shape_manual but without success.

Don't know what I'm missing, any help would be appreciated.

CodePudding user response:

Here is a partial solution.
If you want elements to appear in the legend, you need to map them inside aesthetics.
This should be an alternative to do 3 separated legends, I don't know if it can be easily done with ggplot, without going deeper.

library("tidyverse")
library("ggplot2")
library("sf")
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library("rnaturalearth")
library("rnaturalearthdata")

world <- ne_countries(scale = "medium", returnclass = "sf")

x1.SST <- c(-2,0,0,-2)
x2.SST <- c(5,10,13,15)
y1.SST <- c(37,40,36,35)
y2.SST <- c(41,45,45,45)

x1.WV <- c(1,2.5,-3)
x2.WV <- c(5,8,10.25)
y1.WV <- c(37.5,39.5,35)
y2.WV <- c(40.5,43.75,45)

x1.CM <- c(2,1,8)
x2.CM <- c(3.5,3.5,14)
y1.CM <- c(39,41,45.5)
y2.CM <- c(40,44,47.5)

d.SST <- data.frame(x1=x1.SST, x2=x2.SST, y1=y1.SST, y2=y2.SST,
                    SST=c('MALL SST','AUD SST','VAIA SST','WMED'), r=c(1,2,3,4))
d.WV <- data.frame(x1=x1.WV, x2=x2.WV, y1=y1.WV, y2=y2.WV,
                   WV=c('MALL WV','AUD WV','VAIA WV'), r=c(1,2,3))
d.CM <- data.frame(x1=x1.CM, x2=x2.CM, y1=y1.CM, y2=y2.CM,
                   CM=c('MALL CM','AUD CM','VAIA CM'), r=c(1,2,3))

# create a new tibble with bound data from the 3 previous data frames
d = d.SST %>% 
  rename(group2 = SST) %>% 
  mutate(group1 = "SST") %>% 
  bind_rows(d.WV %>% rename(group2 = WV) %>% mutate(group1 = "WV")) %>% 
  bind_rows(d.CM %>% rename(group2 = CM) %>% mutate(group1 = "CM"))

world %>% 
  ggplot()   
  geom_sf(fill = "lavender")   
  coord_sf(xlim = c(-5, 16), ylim = c(34,48))   
  xlab("")   
  ylab("")   
  geom_rect(data = d, 
            aes(xmin = x1, 
                xmax = x2, 
                ymin = y1, 
                ymax = y2, 
                color = group2,
                size = group1,
                fill = group1,
                alpha = group1,
                linetype = group1))   
  scale_fill_manual("legend1", values = c("SST" = NA, "WV" = NA, "CM" = "blue"))  
  scale_alpha_manual("legend1", values = c("SST" = 0, "WV" = 0, "CM" = 0.2))  
  scale_size_manual("legend1", values = c("SST" = 1, "WV" = 1, "CM" = 0.5))  
  scale_linetype_manual("legend1", values = c("SST" = 1, "WV" = 2, "CM" = 1))  
  scale_color_viridis_d("legend2")  
  theme_light()  
  guides(color = guide_legend(override.aes = list(fill = NA), order = 2),
         fill = guide_legend(override.aes = list(color = "black")))

Created on 2021-10-01 by the reprex package (v2.0.0)

  • Related