rplotterracolor-gradient

Applying same color gradient for three SpatRaster maps with terra::plot in R


I have a SpatRaster created with the terra package in R, and I have two groupings of points within the larger SpatRaster, which I then separate into groups to observe the groupings with more detail. I use terra::plot to plot the larger SpatRaster and the individual groups, but I want to keep the gradient scale the same for all of the plots. The issue is that the range of values for each of the plots differs, and I haven't been able to figure out how to set the lower and upper limits for the color gradient of each terra::plot to be the same so the colors are consistent.

The ggplot2 package did not work for this data because it is SpatRaster data, thus scale_color_gradient does not work, I have tried a combination of the col argument in terra::plot, such as

plot(DTM_50570, main = "DTM", col = data.frame(from = 0, to = 2000, (terra.pal = terrain.colors(255))))

plot(DTM_50570, main = "DTM", col = data.frame(from = c(0, 1000), to = c(1000, 2000), col = terrain.colors(255)))

plot(DTM_50570, main = "DTM", col = data.frame(from = c(0:10:2550), to = c(0:10:2550), col = terrain.colors(255)))

to no avail.

The data that I am using is in this link: https://tinitaly.pi.ingv.it/Download_Area1_1.html, section W50570.

Here is the code I use for plotting and separating the groups:

library(terra)

DTM_50570_32632 <- rast(paste0("Downloads/w50570_s10/w50570_s10/w50570_s10.tif"))
DTM_50570 <- project(x = DTM_50570_32632, "EPSG:4326")

DTM_longitude <- c(11.80111, 11.80222, 11.80333, 11.95111, 11.95222, 11.95333)
DTM_latitude <-c(45.98333, 45.98777, 45.98555, 45.94111, 45.94888, 45.94333)

group_1_extent <- ext(11.80, 11.81, 45.98, 45.99)
DTM_group_1 <- crop(DTM_50570, group_1_extent)

group_2_extent <- ext(11.95, 11.96, 45.94, 45.95)
DTM_group_2 <- crop(DTM_50570, group_2_extent)

DTM_longitude_group_1 <- c(11.80111, 11.80222, 11.80333)
DTM_latitude_group_1 <-c(45.98333, 45.98777, 45.98555)

DTM_longitude_group_2 <- c(11.95111, 11.95222, 11.95333)
DTM_latitude_group_2 <-c(45.94111, 45.94888, 45.94333)

par(mfrow = c(1, 3))
plot(DTM_50570, main = "DTM")
points(DTM_longitude, DTM_latitude, pch = 20)

plot(DTM_group_1, main = "DTM group 1")
points(DTM_longitude_group_1, DTM_latitude_group_1, pch = 20)

plot(DTM_group_2, main = "DTM group 2")
points(DTM_longitude_group_2, DTM_latitude_group_2, pch = 20)

And the resulting plots (that all have different color gradient scales) DTM all plots


Solution

  • DTM_50570, DTM_group_1, and DTM_group_2 have different ranges of elevation values because DTM_group_1 and DTM_group_2 are subsets of DTM_50570. By default, terra::plot scales the color gradient to the min/max of each raster, leading to inconsistent color scales.

    Your attempts to use col with a data.frame didn’t work because the syntax for col in terra::plot expects either a vector of colors (e.g., from terrain.colors(255)) or a function, not a data.frame. Additionally, you need to pair this with a fixed range to ensure consistency.

    Find the Global Range

    Compute the minimum and maximum elevation values across all three rasters (DTM_50570, DTM_group_1, DTM_group_2).

    Define a Color Palette

    Use terrain.colors(255) (or another palette) to create a consistent set of colors.

    Set the Range in plot

    Use the range argument in terra::plot to enforce the same value range for all plots, ensuring the color gradient maps values consistently.

    Apply the Same Colors

    Use the col argument to apply the same palette to all plots.

    library(terra)
    
    DTM_50570_32632 <- rast("Downloads/w50570_s10/w50570_s10/w50570_s10.tif")
    DTM_50570 <- project(x = DTM_50570_32632, "EPSG:4326")
    
    DTM_longitude <- c(11.80111, 11.80222, 11.80333, 11.95111, 11.95222, 11.95333)
    DTM_latitude <- c(45.98333, 45.98777, 45.98555, 45.94111, 45.94888, 45.94333)
    
    group_1_extent <- ext(11.80, 11.81, 45.98, 45.99)
    DTM_group_1 <- crop(DTM_50570, group_1_extent)
    
    group_2_extent <- ext(11.95, 11.96, 45.94, 45.95)
    DTM_group_2 <- crop(DTM_50570, group_2_extent)
    
    DTM_longitude_group_1 <- c(11.80111, 11.80222, 11.80333)
    DTM_latitude_group_1 <- c(45.98333, 45.98777, 45.98555)
    
    DTM_longitude_group_2 <- c(11.95111, 11.95222, 11.95333)
    DTM_latitude_group_2 <- c(45.94111, 45.94888, 45.94333)
    
    # Step 1: Compute the global range across all rasters
    global_min <- min(minmax(DTM_50570)[1], minmax(DTM_group_1)[1], minmax(DTM_group_2)[1])
    global_max <- max(minmax(DTM_50570)[2], minmax(DTM_group_1)[2], minmax(DTM_group_2)[2])
    global_range <- c(global_min, global_max)
    
    # Step 2: Define a common color palette
    col_palette <- terrain.colors(255)
    
    # Step 3: Plot all rasters with the same range and color palette
    par(mfrow = c(1, 3))
    
    plot(DTM_50570, main = "DTM", range = global_range, col = col_palette)
    points(DTM_longitude, DTM_latitude, pch = 20)
    
    plot(DTM_group_1, main = "DTM group 1", range = global_range, col = col_palette)
    points(DTM_longitude_group_1, DTM_latitude_group_1, pch = 20)
    
    plot(DTM_group_2, main = "DTM group 2", range = global_range, col = col_palette)
    points(DTM_longitude_group_2, DTM_latitude_group_2, pch = 20)