Skip to content

Instantly share code, notes, and snippets.

@dsparks
Last active August 19, 2022 06:54
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save dsparks/3710171 to your computer and use it in GitHub Desktop.
Save dsparks/3710171 to your computer and use it in GitHub Desktop.
ggplot2 heatmap with "spectral" palette
doInstall <- TRUE # Change to FALSE if you don't want packages installed.
toInstall <- c("ggplot2", "reshape2", "RColorBrewer")
if(doInstall){install.packages(toInstall, repos = "http://cran.us.r-project.org")}
lapply(toInstall, library, character.only = TRUE)
# Generate a random matrix
# This can be any type of numeric matrix,
# though we often see heatmaps of square correlation matrices.
nRow <- 9
nCol <- 16
myData <- matrix(rnorm(nRow * nCol), ncol = nCol)
rownames(myData) <- letters[1:nRow]
colnames(myData) <- LETTERS[1:nCol]
# Replace with numbers that actually have a relationship:
for(ii in 2:ncol(myData)){ myData[, ii] <- myData[, ii-1] + rnorm(nrow(myData)) }
for(ii in 2:nrow(myData)){ myData[ii, ] <- myData[ii-1, ] + rnorm(ncol(myData)) }
# For melt() to work seamlessly, myData has to be a matrix.
longData <- melt(myData)
head(longData, 20)
# Optionally, reorder both the row and column variables in any order
# Here, they are sorted by mean value
longData$Var1 <- factor(longData$Var1, names(sort(with(longData, by(value, Var1, mean)))))
longData$Var2 <- factor(longData$Var2, names(sort(with(longData, by(value, Var2, mean)))))
# Define palette
myPalette <- colorRampPalette(rev(brewer.pal(11, "Spectral")), space="Lab")
zp1 <- ggplot(longData,
aes(x = Var2, y = Var1, fill = value))
zp1 <- zp1 + geom_tile()
zp1 <- zp1 + scale_fill_gradientn(colours = myPalette(100))
zp1 <- zp1 + scale_x_discrete(expand = c(0, 0))
zp1 <- zp1 + scale_y_discrete(expand = c(0, 0))
zp1 <- zp1 + coord_equal()
zp1 <- zp1 + theme_bw()
print(zp1)
@onertipaday
Copy link

It should be:
longData$X1 <- factor(longData$Var1, names(sort(with(longData, by(value, Var1, mean)))))
longData$X2 <- factor(longData$Var2, names(sort(with(longData, by(value, Var2, mean)))))

Instead of:
longData$X1 <- factor(longData$X1, names(sort(with(longData, by(value, X1, mean)))))
longData$X2 <- factor(longData$X2, names(sort(with(longData, by(value, X2, mean)))))

@dsparks
Copy link
Author

dsparks commented Nov 15, 2012

Fixed, thanks!

@msund
Copy link

msund commented Aug 21, 2014

This is cool @dsparks. I'm working on Plotly and we're working on translating ggplot2 plots into interactive, web-based plots. We did it with this one here: https://plot.ly/~RgraphingAPI/1995.

You add py$ggplotly() to the end of the call to get it. See: plot.ly/ggplot2 for more. Very cool plot!

@scienceforever
Copy link

Nowadays, melt() generates "Var1" and "Var2" column names, instead of "X1" and "X2"

@dsparks
Copy link
Author

dsparks commented Oct 16, 2014

Alternatively, use rje::cubeHelix(100) in place of myPalette(100).

@afaquekhan
Copy link

simple execution gives the following error:
Error in by.default(value, Var1, mean) : object 'Var1' not found
Am I doing anything wrong ?

@long-jian
Copy link

Is there any way to set 0 to the light yellow? Or should I standardized the value?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment