问题
I have some imaging data with very faint contrast and quite a bit of noise, and when I display it with a linear colour scale it doesn't show well. In imaging software such as imageJ or photoshop, there's a tonal curve that one can tune to bump the contrast in a nonlinear fashion and effectively stretch the scale on some region of interest to see more details.
As a simplest case of such nonlinear tuning parameter, @BrianDiggs pointed out the bias
argument to colorRamp
, which still requires previous tranformation of the data to be in [0, 1].
I'd like to generalise the non-linear scale to other functionals than x^gamma
, therefore the function below doesn't actually use bias
in colorRamp
but does the transformation on the data side.
I feel like I'm reinventing the wheel; is there already such a tool for continuous colour scales in R?
回答1:
Here is a possible solution,
set.seed(123)
x <- sort(runif(1e4, min=-20 , max=120))
library(scales) # rescale function
curve_pal <- function (x, colours = rev(blues9),
fun = function(x) x^gamma,
n=10, gamma=1)
{
# function that maps [0,1] -> colours
palfun <- colorRamp(colors=colours)
# now divide the data in n equi-spaced regions, mapped linearly to [0,1]
xcuts <- cut(x, breaks=seq(min(x), max(x), length=n))
xnum <- as.numeric(xcuts)
# need to work around NA values that make colorRamp/rgb choke
testNA <- is.na(xnum)
xsanitised <- ifelse(testNA, 0, fun(rescale(xnum)))
# non-NA values in [0,1] get assigned their colour
ifelse(testNA, NA, rgb(palfun(xsanitised), maxColorValue=255))
}
library(gridExtra)
grid.newpage()
grid.arrange(rasterGrob(curve_pal(x, gamma=0.5), wid=1, heig=1, int=F),
rasterGrob(curve_pal(x, gamma=1), wid=1, heig=1, int=F),
rasterGrob(curve_pal(x, gamma=2), wid=1, heig=1, int=F),
nrow=1)
来源:https://stackoverflow.com/questions/18036849/gradient-colour-scale-with-gamma-parameter