How can I define a "heated body" or "black-body radiation" color scheme for color-coding sequential data in R?
Standard R color palettes don't give an indication of ordinal, interval or ratio scaling. The rainbow palette is problematic for multiple reasons described by Borland & Taylor ("Rainbow Color Map (Still) Considered Harmful", IEEE Computer Graphics and Applications, 2007). (See also xkcd's painbow.) They instead recommend using a "black-body radiation" color palette, which is elsewhere called a "heated body" palette:

Unfortunately, I don't seem to find an R function to create this palette. ColorBrewer and the RColorBrewer package are not helpful (although this palette comes close), especially if I need more than 9 colors.
This question at CrossValidated is related: Most effective use of colour in heat/contour maps
grDevices::colorRamp()Here is a function:
blackBodyRadiationColors <- function(x, max_value=1) {
# x should be between 0 (black) and 1 (white)
# if large x come out too bright, constrain the bright end of the palette
# by setting max_value lower than 1
foo <- colorRamp(c(rgb(0,0,0),rgb(1,0,0),rgb(1,1,0),rgb(1,1,1)))(x*max_value)/255
apply(foo,1,function(bar)rgb(bar[1],bar[2],bar[3]))
}
And here is an example, where we indicate the years in a seasonplot of the AirPassengers data using the rainbow vs. the black-body radiation color palette:

library(forecast)
n.colors <- ceiling(length(AirPassengers)/frequency(AirPassengers))
colors.blackBody <- blackBodyRadiationColors(seq(0,0.6,length.out=n.colors))
colors.rainbow <- rainbow(n.colors)
opar <- par(mfrow=c(2,1),mai=c(.5,1.2,.1,.1))
seasonplot(AirPassengers, col=colors.rainbow,
pch=19,year.labels=TRUE,xlab="",main="",ylab="Rainbow\npalette")
seasonplot(AirPassengers, col=colors.blackBody,ylab="Black-body\nradiation palette",
pch=19,year.labels=TRUE,xlab="",main="",ylab="Black-body\nradiation palette")
par(opar)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With