How to add colorbar with perspective plot in R

后端 未结 2 1764
闹比i
闹比i 2021-01-03 07:04

May be it is very simple to do, but after hours of searching I didn\'t able to find how to add colorbar beside the persp plot using R. Could anyone kindly help? Thanks.

相关标签:
2条回答
  • 2021-01-03 07:38

    It's possible to add a legend using image.plot in the fields package. Using an example from ?persp:

    library(fields)
    
    ## persp example code
    par(bg = "white")
    x <- seq(-1.95, 1.95, length = 30)
    y <- seq(-1.95, 1.95, length = 35)
    z <- outer(x, y, function(a, b) a*b^2)
    nrz <- nrow(z)
    ncz <- ncol(z)
    # Create a function interpolating colors in the range of specified colors
    jet.colors <- colorRampPalette( c("blue", "green") )
    # Generate the desired number of colors from this palette
    nbcol <- 100
    color <- jet.colors(nbcol)
    # Compute the z-value at the facet centres
    zfacet <- (z[-1, -1] + z[-1, -ncz] + z[-nrz, -1] + z[-nrz, -ncz])/4
    # Recode facet z-values into color indices
    facetcol <- cut(zfacet, nbcol)
    persp(x, y, z, col = color[facetcol], phi = 30, theta = -30, axes=T, ticktype='detailed')
    
    ## add color bar
    image.plot(legend.only=T, zlim=range(zfacet), col=color)
    

    EDIT thanks to @Marc_in_the_box: the range of the colorbar is defined by zfacet, not by z persp with colorbar

    0 讨论(0)
  • 2021-01-03 08:02

    persp has a tricky way of computing colors based on the mid points of the facets. This makes your work a bit difficult in extracting the color levels, but I think I have found a way. In any case, layout is probably your best bet for splitting your device and adding a color bar:

    Example:

    layout(matrix(1:2, nrow=1, ncol=2), widths=c(4,1), heights=1)
    par(bg = "white", mar=c(4,4,1,1))
    x <- seq(-1.95, 1.95, length = 30)
    y <- seq(-1.95, 1.95, length = 35)
    z <- outer(x, y, function(a, b) a*b^2)
    nrz <- nrow(z)
    ncz <- ncol(z)
    # Create a function interpolating colors in the range of specified colors
    jet.colors <- colorRampPalette( c("blue", "green") )
    # Generate the desired number of colors from this palette
    nbcol <- 100
    color <- jet.colors(nbcol)
    # Compute the z-value at the facet centres
    zfacet <- (z[-1, -1] + z[-1, -ncz] + z[-nrz, -1] + z[-nrz, -ncz])/4
    # Recode facet z-values into color indices
    facetcol <- cut(zfacet, nbcol)
    persp(x, y, z, col = color[facetcol], phi = 30, theta = -30)
    
    labs <- levels(facetcol)
    tmp <- cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs) ),
          upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs) ))
    
    par(mar=c(10,0,10,5))
    image(x=1, y=rowMeans(tmp), matrix(rowMeans(tmp), nrow=1, ncol=nbcol), col=color, axes=FALSE, xlab="", ylab="")
    axis(4)
    box()
    

    enter image description here

    btw, I realized that the last example from persp looks to have an error in it's calculation of facet values - as is, they are the sum of the corner values, and need to be divided by 4 in order to use them directly in extracting the color break points:

    # Compute the z-value at the facet centres
    zfacet <- z[-1, -1] + z[-1, -ncz] + z[-nrz, -1] + z[-nrz, -ncz]
    # Recode facet z-values into color indices
    facetcol <- cut(zfacet, nbcol)
    
    #should be:
    # Compute the z-value at the facet centres
    zfacet <- (z[-1, -1] + z[-1, -ncz] + z[-nrz, -1] + z[-nrz, -ncz]) / 4
    # Recode facet z-values into color indices
    facetcol <- cut(zfacet, nbcol)
    
    0 讨论(0)
提交回复
热议问题