1

I have a function, which uses spatstat's colourmap function to generate a color scale to a plot. The colourmap function uses the image function to plot the color scale. Here is an example:

library(spatstat)

set.seed(1)
dat <- data.frame(x = 1:10, y = 10:1, z = rnorm(10,6,8))

plot_this <- function(x,y,z) {
colpal <- colorRampPalette(c("red", "blue"), bias=1)(20)
colmap <- colourmap(colpal, range = range(z))
layout(matrix(c(1,2), nrow = 1), widths = c(9,1))
par(mar = c(4, 4, 2.5, 1) + 0.1)
plot(x, y, type = "p", bg = colmap(z), pch = 21, cex = 3)
par(mar=c(1,0.5,3,2))
plot(colmap, vertical = TRUE)}

plot_this(dat$x, dat$y, dat$z)

enter image description here

I would like to plot several of these plots side-by-side, but my attempts fail:

par(mfcol = c(1,2))
plot_this(dat$x, dat$y, dat$z)
plot_this(dat$x, dat$y, dat$z)

dev.off()
layout(matrix(c(1,2), nrow = 1))
plot_this(dat$x, dat$y, dat$z)
plot_this(dat$x, dat$y, dat$z)

dev.off()
library(gridExtra)
grid.arrange(grob(plot_this(dat$x, dat$y, dat$z)), grob(plot_this(dat$x, dat$y, dat$z)), ncol = 2)

I found a tread, where Dr. Paul Murrell says that image.plot is incompatible with layout. However, I do believe that the problem is solvable. How can I improve the code to enable plotting using layout or par?

I would like to do something like following, but to include the color scale for each plot separately:

plot_this2 <- function(x,y,z) {
colpal <- colorRampPalette(c("red", "blue"), bias=1)(20)
colmap <- colourmap(colpal, range = range(z))
plot(x, y, type = "p", bg = colmap(z), pch = 21, cex = 3)
}

layout(matrix(c(1,2), nrow = 1))
plot_this2(dat$x, dat$y, dat$z)
plot_this2(dat$x, dat$y, dat$z)

enter image description here

EDIT: @IShouldBuyABoat suggested looking into gridBase. There is a nice SO answer for mixing base and ggplot graphics, but I cannot find a working combination of grid functions to make the plot. Here is one of the trials:

library(gridBase)

plot_this <- function(x,y,z) {
plot.new()
colpal <- colorRampPalette(c("red", "blue"), bias=1)(20)
colmap <- colourmap(colpal, range = range(dat$z))
gl <- grid.layout(nrow=1, ncol=2, widths = c(9,1))
vp.1 <- viewport(layout.pos.col=1, layout.pos.row=1) 
vp.2 <- viewport(layout.pos.col=2, layout.pos.row=1) 
pushViewport(viewport(layout=gl))
pushViewport(vp.1)
par(new=TRUE, fig=gridFIG(), mar = c(4, 4, 2.5, 1) + 0.1)
plot(dat$x, dat$y, type = "p", bg = colmap(dat$z), pch = 21, cex = 3)
popViewport(1)
pushViewport(vp.2)
par(new=TRUE, fig=gridFIG(), mar = c(1,0.5,3,2))  
print(plot(colmap, vertical = TRUE))
popViewport(0)}

graphics.off()
plot.new()
gl <- grid.layout(ncol = 2, nrow = 1)
vp.1 <- viewport(layout.pos.col=1, layout.pos.row=1) 
vp.2 <- viewport(layout.pos.col=2, layout.pos.row=1) 
pushViewport(viewport(layout=gl))
pushViewport(vp.1)
plot_this(dat$x, dat$y, dat$z)
popViewport()
pushViewport(vp.2)
par(new=TRUE, fig=gridFIG())
plot_this(dat$x, dat$y, dat$z)
popViewport(1)
Community
  • 1
  • 1
Mikko
  • 7,530
  • 8
  • 55
  • 92
  • grid is a different plotting paradigm. You probably need to look at the 'gridBase' package to get the capability to mix base-graphics and grid-graphics. (you should also clarify whether the plotting of multiple colorbars , one to each plot region, is what you wanted. – IRTFM Mar 17 '14 at 08:18
  • @IShouldBuyABoat I tried to `grob()` the plots, but they become plotted when using `grob` (unlike `ggplot2` or other grid-graphics) and seem to override `grid.arrange`. – Mikko Mar 17 '14 at 08:24
  • Please read comments for meaning before posting further vague descriptions of errors. And then edit your question rather than creating along trail of poorly formatted and insufficiently specific comments. – IRTFM Mar 17 '14 at 08:28
  • @IShouldBuyABoat Why the aggressive tone? I think I did understand your meaning, although your comment was not that very precise either, especially before the edits. You probably meant something like this? http://stackoverflow.com/questions/14999802/how-to-use-r-base-plots-in-grid-newpage. – Mikko Mar 17 '14 at 08:36

1 Answers1

0

The main problem is that you can only use one kind of layout-control mechanism at a time. The command layout is not compatible with manipulating the layout using par(mfrow) etc.

A solution would be to remove the layout call from the function plot_this. Instead, inside plot_this, first create a basic plot coordinate system by

plot(0,0,xlim=c(0,1), ylim=c(0,1), type="n", axes=FALSE)

Then add the scatterplot using points(...., add=TRUE) and add the colour map using plot(..., add=TRUE, xlim, ylim) where the latter is a call to the spatstat function plot.colourmap.

Adrian Baddeley
  • 1,956
  • 1
  • 8
  • 7