Search code examples
rtextrasterlatticerastervis

Subscript/superscript characters in rasterVis::levelplot strip labels


Can we include subscript/superscript characters in rasterVis::levelplot strip labels?

Consider the following RasterStack, s:

library(rasterVis)
s <- stack(replicate(2, raster(matrix(runif(9), 3))))

The default plot method for Raster* objects allows expressions to be passed to the main argument:

plot(s, main=expression(Something, Something[2]))

enter image description here

With rasterVis::levelplot, strip names are passed via the names.attr argument, but it seems these are coerced to character before eventually being passed to lattice::levelplot with strip.custom(factor.levels = names.attr).

The result is:

levelplot(s, names.attr=expression(Something, Something[2]))

enter image description here

Short of modifying the source, is there a way to use expressions (or otherwise achieve subscript/superscript characters) in strip labels of rasterVis::levelplot?


Solution

  • You might think that rasterVis::levelplot was using the code of lattice::levelplot and to an extent that turns out to be the case, but a bunch of data transformation occurs first. The S4-method cannot be seen by using the signature with x="RasterBrick", but rather needs x="Raster".

    showMethods("levelplot", classes="RasterStack", includeDefs=TRUE)
    
    getMethod("levelplot", signature=c(x="Raster", data="missing"))
    

    That shows that the code constructing the strips is defined as:

        ....
                strip = strip.custom(factor.levels = names.attr), 
        ....
    

    I would have guessed that factor.levels would have been the correct parameter to pass an expression to. There is a coercion step that is causing the failure. So you need to hack the code to allow an expression to make it through. If I comment out the coercion with as.character:

            else {
             # names.attr <- as.character(names.attr)
             if (length(names.attr) != nlayers(object)) 
                 stop("Length of names.attr should match number of layers.")
    

    Using:

    setMethod( "levelplot:   {
      function code
      },  signature= c(x="Raster", data="missing"))
    

    And copy two unexported function from rasterVis to the the global environment I get success:

    drawMargin <- rasterVis:::drawMargin
    constructMargin <- rasterVis:::constructMargin
    

    And pass the uncoerced expressions to 'factor.levels' via names.attr:

    png(); print(levelplot(s, names.attr=expression(Something, Something[2])) );dev.off()
    

    enter image description here