Search code examples
rggplot2fillr-raster

Adding continuous/gradient fill to map


After lurking around for some time, this is my first question here - I'm an absolute novice so please forgive any lack of knowledge about this forum's customs and technical details of R.

I want to plot a map of Germany, in which the fill of the federal states reflects the inhabitants' preferences, like I have done here: Excel example

My data looks as follows:

Bundesland Sausage
Baden-Württemberg 28,7%
Bayern 31,7%
Berlin 20%
Brandenburg 20,8%
Bremen 19,2%
Hamburg 20,6%
Hessen 24,4%
Mecklenburg-Vorpommern 24,8%
Niedersachsen 26,5%
Nordrhein-Westfalen 26,6%
Rheinland-Pfalz 28,9%
Saarland 27,3%
Sachsen 22,5%
Sachsen-Anhalt 25%
Schleswig-Holstein 26,6%
Thüringen 24,1%

I want to plot the map like this:

#loading libraries
    library(ggplot2)
    library(raster)

#retrieving map
germany <- getData(country = "Germany", level = 1)

#drawing map as plot
ggplot() +
geom_polygon(data = germany,
             aes(x = long, y = lat, group = group))

Which provides me with this this plot.

My question now is: how can I integrate the data from the table above as a gradient fill for the different federal states?

And: is it possible to show the percentages in the plot in the respective federal state instead of having a gradient legend next to the plot?

Thanks a lot for any advice, it is much appreciated!


Solution

  • You can do this with the terra package like this

    library(geodata)
    library(terra)
    
    dat <- data.frame(Bundesland = c("Baden-Württemberg", "Bayern", "Berlin", "Brandenburg", "Bremen", "Hamburg", "Hessen", "Mecklenburg-Vorpommern", "Niedersachsen", "Nordrhein-Westfalen", "Rheinland-Pfalz", "Saarland", "Sachsen", "Sachsen-Anhalt", "Schleswig-Holstein", "Thüringen"
    ), Sausage = c(0.287, 0.317, 0.2, 0.208, 0.192, 0.206, 0.244, 0.248, 0.265, 0.266, 0.289, 0.273, 0.225, 0.25, 0.266, 0.241))
    
    
    germany <- geodata::gadm("Germany", 1, path=".")
    germany = merge(germany, dat, by.x="NAME_1", by.y="Bundesland")
    
    plot(germany, "Sausage", col=heat.colors(25))
    text(germany, paste0(round(germany$Sausage * 100), "%"), halo=TRUE, cex=0.8)
    

    enter image description here

    To avoid the overlap of the Berlin and Brandenburg labels (and here also suppressing the legend)

    xy <- crds(centroids(germany))
    i <- which(germany$NAME_1 == "Brandenburg")
    xy[i, ] <- xy[i,] + c(0.2, -0.4)
    
    plot(germany, "Sausage", col=heat.colors(25), lwd=2, legend=FALSE)
    text(vect(xy), paste0(round(germany$Sausage * 100), "%"), halo=TRUE, cex=0.7)
    

    enter image description here

    And to reproduce your gray-scale map without axes or title:

    plot(germany, "Sausage", col=rev(gray(1:20 / 20)), border=gray(0.9), axes=FALSE, legend=FALSE, main="", mar=0)
    text(vect(xy), paste0(round(germany$Sausage * 100), "%"), halo=TRUE, cex=0.7)
    

    enter image description here