Dynamic Values to scale_color_manual and scale_shape_manual

I'm trying to use ggplot to create a large number of maps for each unique value of store_type. Each point should be a different color/shape combination based on an underlying county-level value(e.g. if county_type is 'A', the shape should be a plus sign).

The issue I'm having is that I've hard-coded the color/shape values into scale_color_manual and scale_shape_manual, and not every value of county_type is present in each subset filtered by unique values of store type, e.g. there are no stores of type 'pear' in counties of type 'C'. This means that the color/shape combinations are inconsistent from map to map. So if you look at the plot for store_type == 'peach', stores in type A counties are blue crosses, B counties are red triangles, C counties are seagreen dots. Stores of type 'apple' only exist in A and C counties, so A sites are still blue crosses but it incorrectly depicts C counties as red triangles(since it has just moved to the next color/shape combination on the scale).

How can I avoid hard-coding these values so that A sites are always blue crosses, B sites are always red triangles, etc. regardless of the combination of sites that is in each subset? Reprex below:

library(dplyr)
#> Warning: package 'dplyr' was built under R version 3.6.3
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(sf)
#> Warning: package 'sf' was built under R version 3.6.3
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(ggplot2)
library(ggthemes)

set.seed(159)


nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)

nc_counties <- sort(as.character(unique(nc$NAME)))

id          <- 1:10
lon         <- runif(10, -80, -77)
lat         <- runif(10, 35, 36)
store_type  <- sample(rep(c('apple', 'orange', 'peach', 'pear'), 3),10)
county      <- sample(nc_counties, 10, replace = FALSE)
county_type <- sample(rep(c('A', 'B', 'C'),4),10, replace = FALSE)

fruit_stands <- data.frame(id, lon, lat, store_type, county, county_type,stringsAsFactors = FALSE)

fruit_stands <- filter(fruit_stands, !(store_type == 'pear' & county_type == 'C'))

fruit_plots <- list()

for(i in unique(fruit_stands$store_type)){
      
      fruit_plots[[i]] <-   ggplot(data=filter(fruit_stands, store_type == i)) +
            geom_sf(data=nc, alpha= 0.35,key_glyph = 'rect')+
            coord_sf(datum = NA)+
            geom_point(data=filter(fruit_stands, store_type == i), 
                       aes(x=lon, y=lat, shape=county_type, colour=county_type), 
                       size=1.75,alpha=0.60)+
            scale_color_manual(values= c('blue', 'red', 'seagreen2', 'gold'), 
                               aesthetics = c('color'),
                               name= 'County Type')+
            scale_shape_manual(values = c(3,17,19,23),
                               name= 'County Type')+
            labs(title=i)+
            theme_map()
      
      
}

print(fruit_plots)
#> $orange

#> 
#> $peach

#> 
#> $apple

#> 
#> $pear

Created on 2020-09-23 by the reprex package (v0.3.0)

You can manually set the relationship between the color or shape and the factor value. I do not have the sf package but here is a facet plot that I think demonstrates the method.

set.seed(1)
id          <- 1:10
lon         <- runif(10, -80, -77)
lat         <- runif(10, 35, 36)
store_type  <- sample(rep(c('apple', 'orange', 'peach', 'pear'), 3),10)
#county      <- sample(nc_counties, 10, replace = FALSE)
county_type <- sample(rep(c('A', 'B', 'C'),4),10, replace = FALSE)

fruit_stands <- data.frame(id, lon, lat, store_type, county_type,stringsAsFactors = FALSE)
COLORS <- c('A' = 'blue', 'B' = 'red', 'C' = 'seagreen2', 'D' = 'gold')
SHAPES <- c('A' = 3,'B' = 17,'C' = 19,'D' = 23)

library(ggplot2)
ggplot(fruit_stands, aes(lon, lat, color = county_type, shape = county_type)) +
  geom_point() +
  facet_wrap(~store_type) +
  scale_color_manual(values = COLORS) +
  scale_shape_manual(values = SHAPES)

Created on 2020-09-23 by the reprex package (v0.3.0)

2 Likes

Fantastic, that worked wonderfully.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.