Reputation: 85
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)
Plot 2 (absolute-scale)
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
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
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))
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)
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])
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