Home > Net >  Combine ggplot legends with varying labels
Combine ggplot legends with varying labels

Time:12-25

We want to create a graph/legend that uses shape to code one factor and color for another factor, and have the legend like a table, columns for one factor and rows for the other. The trick is, the legend labels have to be different in the two columns, something like this mockup: enter image description here

Here are test data and a failed attempt. The factor "fromto" represents the columns; "match" the rows, linking the two elements that should have the same color.

library(ggplot2)
library(sf)

# Map limits
XLIM <- c( -112.2, -104 )
YLIM <- c( 33.8, 39.8 )

# DUMMY DATA
DAT <- "fromto match label lat long
Procurement flaghi 1-2 39.73921 -103.99030
Procurement flaglo 2-3 39.06831 -107.56443
Procurement pine 3-4 35.09633 -105.64020
Procurement taos 4-5 35.19934 -110.65155
Procurement crip 5-6 38.57335 -110.54645
Deployment flaghi 6-7 39.73921 -104.99030
Deployment flaglo 7-8 39.06831 -108.56443
Deployment pine 8-9 35.09633 -106.64020
Deployment taos 9-10 35.19934 -111.65155
Deployment crip 10-11 38.57335 -109.54645"

DAT <- read.table( text=DAT, header=TRUE, stringsAsFactors=FALSE )
DAT <- st_as_sf(x = DAT, 
                coords = c("long", "lat"),
                crs = 4326 )
DAT$fromto <- factor(DAT$fromto)
DAT$match <- factor(DAT$match)
DAT$label <- factor(DAT$label)

p <- ggplot()  

geom_sf( DAT, mapping=aes( shape=fromto, color=match ), size=3 )  
  scale_shape_manual( values=c(16,3), name=NULL )  
  scale_color_manual( values=c("red", "orange", "blue", "black", "green"),
                      labels=DAT$label, name=NULL )  
  coord_sf( xlim=XLIM, ylim=YLIM, crs=26912, default_crs=4326 )
p

enter image description here

CodePudding user response:

Using ggnewscale you could try...

library(ggplot2)
library(sf)
library(ggnewscale)

# Map limits
XLIM <- c( -112.2, -104 )
YLIM <- c( 33.8, 39.8 )

# DUMMY DATA
DAT <- "fromto match label lat long
Procurement flaghi 1-2 39.73921 -103.99030
Procurement flaglo 2-3 39.06831 -107.56443
Procurement pine 3-4 35.09633 -105.64020
Procurement taos 4-5 35.19934 -110.65155
Procurement crip 5-6 38.57335 -110.54645
Deployment flaghi 6-7 39.73921 -104.99030
Deployment flaglo 7-8 39.06831 -108.56443
Deployment pine 8-9 35.09633 -106.64020
Deployment taos 9-10 35.19934 -111.65155
Deployment crip 10-11 38.57335 -109.54645"

DAT <- read.table(text = DAT, header = TRUE)
DAT <- st_as_sf(x = DAT, 
                coords = c("long", "lat"),
                crs = 4326 )

# split data for to enable dual legend based on colour
dat_p <- DAT[DAT$fromto == "Procurement", ]
dat_d <- DAT[DAT$fromto == "Deployment", ]

ggplot()  
  geom_sf(dat_p, mapping = aes(color = match), shape = 3 , size=3 )  
  scale_color_manual(values = c("red", "orange", "blue", "black", "green"),
                     labels = dat_p$label,
                     name = "Procurement" )  
  new_scale_colour() 
  geom_sf(dat_d, mapping = aes(color = match), size=3 )  
  scale_color_manual( values = c("red", "orange", "blue", "black", "green"),
                      labels = dat_d$label,
                      name = "Deployment" )  
  coord_sf(xlim = XLIM, 
           ylim = YLIM, 
           crs = 26912,
           default_crs = 4326)  
  theme(legend.direction = "vertical",
        legend.box = "horizontal",
        legend.position = c(1.025, 0.55),
        legend.justification = c(0, 1))

enter image description here Created on 2021-12-24 by the reprex package (v2.0.1)

  • Related