cols4all
cols4all copied to clipboard
color ramp
@zeileis: does colorspace
also have a color ramp function that I can use? If seems that the
grDevices::colorRamp
does not take only takes objects of class color
?
Reason I ask is that cols4all
currently uses grDevices::colorRamp
, but ideally I'd like to use unrounded RGB values (or polarLAB if desired).
We did not add a color ramp function for two reasons:
- Optionally,
grDevices::colorRamp
already uses CIELAB (space = "Lab"
) for the conversions even if sRGB is the default (space = "rgb"
). Note also that the inputs to this function need to be rounded sRGB coordinates (in the form of hex codes) but the output is not rounded! - We tried to avoid palettes that are constructed by a set of discrete support points. Instead all of our palettes are generated by continuous trajectories in a suitable color space.
My impression is that this should be able to do everything you need? Or do you need functionality for discrete unrounded support points?
Thanks!
A few thinks are unclear:
(blues3_9 = hcl.colors(9, "Blues 3"))
#> [1] "#00366C" "#00538E" "#0072B4" "#468FD0" "#79ABE2" "#A1C4F1" "#C3DBFD"
#> [8] "#E1EEFF" "#F9F9F9"
(blues3_9b = colorRampPalette(blues3_9, space = "Lab")(9))
#> [1] "#00356C" "#00528D" "#0072B3" "#468ED0" "#79ABE1" "#A0C4F1" "#C3DAFD"
#> [8] "#E0EDFF" "#F8F8F8"
Why are these not equal to each other? The colors of "Blues 3" are valid in the CIELAB space, so I would have expected that (at least) the exact same colors are returned, but perhaps I overlooked something.
From my (possibly wrong) understanding colorspace
is used to create the hcl-based palettes in grDevices
(the ones listed with hcl.pals()
). Is that true? Can I also extract the colors (for different n
) in colorspace
? E.g. with something like this?
library(colorspace)
blues3_hcl = hcl_palettes(palette = "Blues 3", n = 9)
as(blues3_hcl, "RGB")
#> Error in as(blues3_hcl, "RGB"): no method or default for coercing "hcl_palettes" to "RGB"
Another slightly off-but still related question:
- Is there a theory or empirical foundation behind the L and C curves in a diverging palette, e.g. from "Purple Green":
hcl.colors(11, "Purple Green") |> specplot()
In hcl_wizard
I noticed that these curves can be adjusted with the P1 and P2 parameters. Are there any best practices of setting those parameters?
@zeileis The questions above are not important for the upcoming CRAN release of cols4all, but I'm still curious:-)
Apologies, I was on Easter vacation and forgot about this. I'll try to have a closer look in the next days.
Finally some follow-up:
- Yes, theoretically these colors should be identical. It's just an artifact from taking integer (0-255) sRGB coordinates, doing the interpolation, and then implicitly using floor rather than round to go back to integers. Thus, this can sometimes decrease an integer sRGB coordinate by 1. This has nothing to do, though, with how the colors were generated in the first place.
Illustration: An olive color with integer sRGB coordinates 120, 160, 100:
So you end up at almost the same coordinates but not quite. If you were to round to integers you would get exactly the same colors. But this is not what thex_hex <- rgb(120, 160, 100, maxColorValue = 255) x_hex ## [1] "#78A064" x_rgb <- t(col2rgb(x)) x_rgb ## red green blue ## [1,] 120 160 100 x_lab <- convertColor(x_rgb/255, from = "sRGB", to = "Lab") x_rgb2 <- convertColor(x_lab, from = "Lab", to = "sRGB") * 255 x_rgb2 ## [,1] [,2] [,3] ## [1,] 120.0005 159.9997 100.0008
rgb()
function does. Instead the 159.9997 is treated like 159, thus reducing the integer sRGB coordinate by 1 compared to the original.rgb(x_rgb2, maxColorValue = 255) ## [1] "#789F64"
- I'm not sure what you are looking for here exactly. If you can tell me what you want to compute exactly, I can hopefully suggest a way to do so...
Background: The HCL palettes are designed by a set of parameters that correspond to trajectories in the three HCL dimensions. The final palettes are set up by selecting points along the trajectories and converting them to sRGB and the corresponding hex colors. Where the parameters are stored and which functions are used for the conversion differs between thegrDevices
andcolorspace
implementations. The former is much more streamlined while the latter has many more convenience features.-
grDevices
: The parameters are stored in the (unexported) data framegrDevices:::.hcl_colors_parameters
.hcl.colors()
extracts the parameters, sets up the trajectories, and then callsgrDevices::hcl()
to compute the hex colors. -
colorspace
: The same parameters are stored in several lists (rather than one data frame), e.g.,colorspace:::seqm.pals
. The functionhcl_palettes()
extracts these parameters and returns a classed data frame withprint
/plot
/summary
methods (but no other coercion methods at the moment). The different palette functions likesequential_hcl()
query these parameters - and optionally tweak them on the fly - and then usescolorspace
's coercion functions to compute the hex colors. The tweaked palettes can also be registered as new palettes etc.
-
- I'm not aware of a "theory" of choosing the power parameters for the chroma and luminance dimensions. We had implemented them for the 2009 "Escaping RGBland" paper in CSDA in order to have a simple way of controlling how quickly the palette increases in chroma and luminance. This allows you to obtain palettes that: (a) highlight only the extreme(s) vs. (b) have relatively colorful colors throughout.
Later on it became clear that these parameters were very helpful for closely approximating palettes from ColorBrewer, CARTO, Crameri, viridis, etc.