rtmap

How to manually set colour of dots in R using tmap


I'm trying to create a map showing the location of wells based on some defined categories. I have categorized each well's water level relative to their full record, categorizing the water levels into terms "Highest-ever", "above-normal", "normal", "below-normal", "Lowest-ever". Using tmap, I would like to show each of these conditions using the following colors "Highest-ever" = dark blue, "above-normal" = light blue, "normal"=green,"below-normal"=yellow, "Lowest-ever" = red

So far I have created an sf file for mapping

Library(tidyverse)
library(sf)
library(spData)
Library(tmap)
Library(tmaptools)

My data

test <- structure(list(well = c(3698L, 3697L, 4702L, 15001L, 1501L, 3737L, 
1674L, 5988L, 1475L, 15017L), con = c("N", "B", "H", "B", "L", 
"B", "N", "A", "N", "B"), x = c(2834091L, 2838342L, 2802911L, 
2845228L, 2834408L, 2834452L, 2838641L, 2834103L, 2803192L, 2929417L
), y = c(6166870L, 6165512L, 6125649L, 6174527L, 6161309L, 6168216L, 
6170055L, 6164397L, 6140763L, 6227467L)), row.names = c(NA, -10L
), class = c("tbl_df", "tbl", "data.frame"))

Create sf file for mapping

test_sf <-test %>% 
  st_as_sf(coords = c("x","y"),crs = 27200,agr="constant")

Obtain background map

HB_map <- nz %>% 
  filter(Name=="Hawke's Bay") %>% 
  read_osm(type = "stamen-terrain")

Plot data over map

qtm(HB_map)+ #this is part of tmap and used to draw a thematic map plot
  tm_shape(nz %>% filter(Name=="Hawke's Bay"))+ #define data source
  tm_borders(col = "grey40", lwd = 2, lty = "solid", alpha = NA)+
  tm_shape(test_sf)+  
tm_dots("con",palette=c(H='blue',A='cyan',N='green',B='yellow',L='red'),stretch.palette = FALSE,size = 0.4,shape =21)

The map produces the right colours but not associated with the correct categories. I could change the order of the colours but the map won't always contain each category and thus the colours would be wrongly assigned again (if that makes sense)


Solution

  • You can convert your con-column to factor. The default order of the levels will be alphabetic, that's how you can assign the colors. If a level is empty, it will still be included in the legend.

    test_sf$con <- as.factor(test_sf$con)
    
    tm_shape(nz %>% filter(Name=="Hawke's Bay"))+ #define data source
      tm_borders(col = "grey40", lwd = 2, lty = "solid", alpha = NA)+
      tm_shape(test_sf[test_sf$con != "H",])+  
      tm_dots(col = "con", palette=c(A='cyan', B='yellow', H='blue',L='red',N='green'), stretch.palette = FALSE,size = 0.4,shape =21)
    
    

    enter image description here

    (read_osm() doesn't work for me..)