Ash
Ash

Reputation: 85

Plotting a GeoTIFF raster in R

I am trying to plot a gridded population count GeoTIFF raster downloaded from here.

library(raster)

#----------------------------#
# Set your working directory #
#----------------------------#

setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) # RStudio IDE preferred

getwd() # Path to your working directory

# Import the GeoTIFF file into R workspace

WorldPop <- raster("nga_ppp_2020_1km_Aggregated_UNAdj.tif")

WorldPop

#---------------------------#
# Data plotted in log-scale #
#---------------------------#

tempcol <- colorRampPalette(c("lightblue", "skyblue", "blue", "yellow", "orange", "red", "darkred"))

plot(log(WorldPop), main = "2020 UN-Adjusted Population Count (log-scale) \n (each grid cell is 1 km x 1 km)", col=tempcol(100), legend.width=2, legend.shrink=1, legend.args=list(text='log(Persons)', side=4, font=2, line=2.5, cex=0.8), axes=T)

#--------------------------------#
# Data plotted in absolute-scale #
#--------------------------------#

plot(WorldPop, main = "2020 UN-Adjusted Population Count (absolute-scale) \n (each grid cell is 1 km x 1 km)", col=tempcol(100), legend.width=2, legend.shrink=1, legend.args=list(text='Persons', side=4, font=2, line=2.5, cex=0.8), axes=T)

Plot 1 (log-scale)

enter image description here

Plot 2 (absolute-scale)

enter image description here

I like the Plot 1 (data in log-scale) but Plot 2 (data in absolute-scale) is not showing any variations in color. How can I make the plot of data in absolute-scale look similar to the one in log-scale?

I am open to using other packages (ggplot2 etc.) or other color palates as long as my plot can distinguish densely populated areas from rural areas. When I used a different GIS tool called Panoply my favorite color palate was something called seminf-haxby.cpt (found here). It looks something like this

enter image description here

I am trying to replicate that in R but the plot in absolute-scale isn't looking good. Any tips or advice for plotting tif rasters in R?

Upvotes: 0

Views: 923

Answers (1)

Robert Hijmans
Robert Hijmans

Reputation: 47191

You can set breaks, something like this:

Example data

url <- "https://data.worldpop.org/GIS/Population/Global_2000_2020_1km_UNadj/2020/NGA/nga_ppp_2020_1km_Aggregated_UNadj.tif"
fname <- basename(url)
if (!file.exists(fname)) download.file(url, fname, mode="wb")

Solution

library(terra)
r <- rast(fname)
plot(r, col=rev(rainbow(10, end=0.7)), breaks=c(0, 10, 25, 50, 100, 250, 1000, 100000))

enter image description here

Now your second question (it is better to not ask two rather different questions at the same time).

The function below extracts the colors from the palette image in your question, and should also work for other palette images organized like yours.

getPal <- function(f) {
    x <- rast(f)
    u <- unique(values(x))
    hex <- rgb(u[,1], u[,2], u[,3], maxColorValue = 255)
    colorRampPalette(hex)
}

pal <- getPal("https://i.sstatic.net/E4d85.png")

par(mar=c(0,0,0,0))
barplot(rep(1, 25), col=pal(25), space=0)

enter image description here

An alternative way to apply breaks is to first use classify. I remove the first color (white)

x <- classify(r, c(0, 10, 25, 50, 100, 250, 1000, 100000))
plot(x, col=pal(8)[-1])

enter image description here

You could change the labels, for example like this

levs <- levels(x)[[1]]
levs[7] <- "> 1000"
levels(x) <- levs

To use this palette in your R code you can create it like this (remove '#FFFFFF' if you do not want to start with white)

ramp <- c('#FFFFFF', '#D0D8FB', '#BAC5F7', '#8FA1F1', '#617AEC', '#0027E0', '#1965F0', '#0C81F8', '#18AFFF', '#31BEFF', '#43CAFF', '#60E1F0', '#69EBE1', '#7BEBC8', '#8AECAE', '#ACF5A8', '#CDFFA2', '#DFF58D', '#F0EC78', '#F7D767', '#FFBD56', '#FFA044', '#EE4F4D')
pal <- colorRampPalette(ramp)

Upvotes: 2

Related Questions