1

Here is a sample script using random numbers instead of real elevation data.

library(gridExtra)
library(spatstat) #im function

elevation <- runif(500, 0, 10)
B <- matrix(elevation, nrow = 20, ncol = 25)
Elevation_Map <- im(B)
custom <- colorRampPalette(c("cyan","green", "yellow", "orange", "red"))
plot(Elevation_Map, col = custom(10), main = NULL)

This is the plot and legend that I get:

enter image description here

This is the legend that I am trying to recreate in R (this one made in Word):

enter image description here

I know this is possible and its probably a simple solution but I've tried using some examples I found online to no avail.

This plot (with real elevation data) is an art piece that will be hung in a gallery, with the elevation plot on 1 board and the legend on a separate board. I tried to get R to plot just the plot without the legend using

plot(Elevation_Map, col = custom(10), main = NULL, legend = NULL)

like I have in the past but for some reason it always plots the legend with the plot. As of right now I'm planning on just cropping the .pdf into 2 separate files to achieve this.

zx8754
  • 52,746
  • 12
  • 114
  • 209
Jay
  • 157
  • 1
  • 2
  • 9
  • 2
    Where does the `im()` function come from? This doesn't look like `ggplot2` at all. – MrFlick Feb 26 '18 at 20:20
  • My apologies MrFlick, the im() function comes from the package "gridExtra". Most of this script is a hand-me-down, so I'm not sure if its easy to recreate without the gridExtra package, I haven't tried. – Jay Feb 26 '18 at 20:52
  • I don't see that function in the `gridExtra` package. Are you maybe using `spatstat`? What does `environment(im)` return? – MrFlick Feb 26 '18 at 20:55
  • @MrFlick I think we can skip `im` function, I think they just want `image` (raster) plot with customised legend changed from `2,4,6,8` to `low,high`. – zx8754 Feb 26 '18 at 20:59
  • @MrFlick You are correct, my bad. The im() function is from spatstat. – Jay Feb 26 '18 at 22:47
  • 1
    The `spatstat` function `plot.im` used here is based on `image.default`. Take a look at the plots produced by `example(plot.im)` and see if there is something useful there. – Ege Rubak Feb 26 '18 at 23:05

2 Answers2

3

Here are two ways of doing it using other packages:

# example data, set seed to reproduce.
set.seed(1); elevation <- runif(500, 0, 10)
B <- matrix(elevation, nrow = 20, ncol = 25)
#Elevation_Map <- im(B)
custom <- colorRampPalette(c("cyan","green", "yellow", "orange", "red"))

1) Using fields package, image.plot(), it is same "base" graphics::image.default() plot but with more arguments for customisation (but couldn't remove the ticks from legend):

library(fields)
image.plot(B, nlevel = 10, col = custom(10),
           breaks = 1:11,
           lab.breaks = c("Low Elevation", rep("", 9), "High Elevation"),
           legend.mar = 10)

enter image description here


2) Using ggplot package, geom_raster function:

library(ggplot2)
library(reshape) # convert matrix to long dataframe: melt

B_melt <- reshape2::melt(B)
head(B_melt)

ggplot(B_melt, aes(X1, X2, fill = value)) +
  geom_raster() +
  theme_void() +
  scale_fill_gradientn(name = element_blank(),
                       breaks = c(1, 9),
                       labels = c("Low Elevation", "High Elevation"),
                       colours = custom(10))

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209
  • Is it not possible to get the continuous gradient using fields package? It's broken into bins unlike the ggplot2 version above. – cryptic0 May 30 '19 at 20:39
2

The code in the original post is using the im class from the spatstat package. The plot command is dispatched to plot.im. Simply look at help(plot.im) to figure out how to control the colour ribbon. The relevant argument is ribargs. Here is a solution:

plot(Elevation_Map, col=custom(10), main="",
     ribargs=list(at=Elevation_Map$yrange, 
                  labels=c("Low Elevation", "High Elevation"),
                  las=1))
Adrian Baddeley
  • 1,956
  • 1
  • 8
  • 7