R levelplot: color green-white-red (white on 0) ac

2019-06-08 20:01发布

The title is pretty much self-descriptive. I want to do a heatmap-like plot with lattice, showing the data values as well, something like in here

However, in my case, I want to color the plot according to one variable (fold.change), but show the values of another variable (p.value).

It would be optimal that the color range is green-white-red, and the white is on 0 (negative fold.change values in green, and positive ones in red).

My last question would be how to change the text size of the title and axis text, remove axis title, and rotate x axis text 45 degrees; I don't find this information in the documentation. Thanks!

This is my MWE so far:

library(lattice)
library(latticeExtra)
library(RColorBrewer)

pv.df <- data.frame(compound = rep(LETTERS[1:8], each = 3), 
                    comparison = rep(c("a/b", "b/c", "a/c"), 8), 
                    p.value = runif(24, 0, 1), 
                    fold.change = runif(24, -2, 6))

myPanel <- function(x, y, z, ...) {
    panel.levelplot(x,y,z,...)
    panel.text(x, y, round(z,1))
}

cols <- rev(colorRampPalette(brewer.pal(6, "RdYlGn"))(20))

png(filename = "test.png", height = 1000, width = 600)
print(
    levelplot(fold.change ~ comparison*compound,
              pv.df,
              panel = myPanel,
              col.regions = cols,
              colorkey = list(col = cols, 
                              at = do.breaks(range(pv.df$fold.change), 20)),
              scales = list(x = list(rot = 90)),
              main = "Total FAME abundance - TREATMENT", 
              type = "g")
)
dev.off()

Which produces this plot:

test

Thanks!

1条回答
不美不萌又怎样
2楼-- · 2019-06-08 20:39

There are several parts to your question. Let's address them one by one:

1: Change labels. This can be done by varying the 3rd argument for panel.text():

myPanel <- function(x, y, z, ...) {
  panel.levelplot(x, y, z, ...)
  panel.text(x, y, round(pv.df$p.value, 2))
}

2: Change color scale with white positioned at 0. Calculate how long each segment of the color scale should be, then define each segment separately:

color.ramp.length <- 20
negative.length <- round(abs(range(pv.df$fold.change)[1]) / 
                           diff(range(pv.df$fold.change)) * 
                           color.ramp.length)
positive.length <- color.ramp.length - negative.length
cols <- c(colorRampPalette(c("seagreen", "white"))(negative.length),
          colorRampPalette(c("white", "firebrick"))(positive.length))

(Note: you can use other color options from here. I just find the colors associated with "red" / "green" an eye sore.)

3: Modify axis titles / labels. Specify the relevant arguments in levelplot().

levelplot(fold.change ~ comparison*compound,
          pv.df,
          panel = myPanel,
          col.regions = cols,
          colorkey = list(col = cols, 
                          at = do.breaks(range(pv.df$fold.change), 
                                         color.ramp.length)),
          xlab = "", ylab = "",              # remove axis titles
          scales = list(x = list(rot = 45),  # change rotation for x-axis text
                        cex = 0.8),          # change font size for x- & y-axis text
          main = list(label = "Total FAME abundance - TREATMENT",
                      cex = 1.5))            # change font size for plot title

plot

查看更多
登录 后发表回答