0

I have an sf-object that I would like to plot. It is a map over counties in Sweden (21 counties) and for each county, I have a value. This value however can be either a positive or negative value, or even an NA. I would like to plot the map over Sweden and color all counties that have NA as white, and then color all other counties with a gradient (depending on value) for all the continuous values. But when I try I only get this error message: Error: Continuous value supplied to discrete scale

This is not my real data but I am not sure how to demonstrate sf-object. So here is just a dataframe with name of county and values (so no coordinates or anything):

data <- data.frame(Diff = c("NA", "NA", "5", "6.89", "9", "-4", "3.56"), 
                   County = c("Halland", "Gotland", "Skane", "Jonkoping", "Gotaland",
                              "Blekinge", "Dalarna"))

ggplot(data) +
  geom_sf(aes(fill = Diff), color = "black") +
  scale_fill_manual(values = c("blue", "yellow", viridis::viridis(4))) +
  coord_sf(datum = NA) 

So I would like to plot the whole map and if a county have an NA, the county should be white. And then I would like to have different color gradient for the values (ranged from negative to positive values) for each county.

Have enayone experienced the same problem?

Peter
  • 11,500
  • 5
  • 21
  • 31
paula456
  • 101
  • 9
  • I'm afraid I get a different error for your example: `Error: stat_sf requires the following missing aesthetics: geometry`. I haven't used `sf` before but `dput` would help to capture the data. My initial thought is that the Diff is stored as a character. Try converting this to a numeric or an integer if that's what's expected e.g. `as.integer(Diff)` – Jonny Phelps Apr 09 '21 at 09:03
  • No, my values are as "numeric". – paula456 Apr 09 '21 at 09:15
  • Ah ok, the `Diff` is stored as a character in the above example as it's wrapped in quotes. E.g. try `class(data$Diff)` – Jonny Phelps Apr 09 '21 at 09:19
  • Yes, that is correct. As I mentioned in my post, I am not sure how to demonstrate an sf-object, so I just demonstrated a dataframe with values and counties. But you are correct, in my dataframe, all my values are characters. But in my original sf-object they are numeric. – paula456 Apr 09 '21 at 09:22
  • I guess that you get the error because with `scale_fill_manual` you are specifying a discrete scale with 6 colors, while your variable is continuous. Why not using `scale_fill_viridis_c(na.value = "white")`? Another option would be `scale_fill_stepsn(colors = c("blue", viridis::viridis(4), "yellow"), na.value = "white")`. – stefan Apr 09 '21 at 09:47

1 Answers1

3

The following code works for me

library(sf)
library(tidyverse)

#Downloading data from DIVA GIS website
get_sweden_map <- function(cong=113) {
  tmp_file <- tempfile()
  tmp_dir  <- tempdir()
  zp <- sprintf("http://biogeo.ucdavis.edu/data/diva/adm/SWE_adm.zip",cong)
  download.file(zp, tmp_file)
  unzip(zipfile = tmp_file, exdir = tmp_dir)
  fpath <- paste(tmp_dir)
  st_read(fpath, layer = "SWE_adm1")
}

swe <- get_sweden_map(114)

#Plot the Counties
plot(swe[5])

data <- tibble(Diff = c("NA", "NA", "5", "6.89", "9", "-4", "3.56"), 
                   County = c("Halland", "Gotland", "Skane", "Jonkoping", "Gotaland",
                              "Blekinge", "Dalarna"))

#Join the data to the swe shapefile
sweden <- swe %>% left_join(data, by=c("NAME_1"="County"))

#Plotting the data
ggplot(sweden) +
  geom_sf(aes(fill = Diff), color = "black") +
  scale_fill_manual(values = c("blue", "yellow", viridis::viridis(4))) +
  coord_sf(datum = NA) 

enter image description here

UseR10085
  • 7,120
  • 3
  • 24
  • 54