On 23/02/2023 4:36 a.m., Sigbert Klinke wrote:
Hi,
I would have expected that I get always 3 colors as result which is not
true:
hcl.colors(3, alpha=c(0, 0.5, 1)) # 3 colors
rainbow(3, alpha=c(0, 0.5, 1)) # 3 colors
heat.colors(3, alpha=c(0, 0.5, 1)) # 3 colors
terrain.colors(3, alpha=c(0, 0.5, 1)) # 6 colors
cm.colors(3, alpha=c(0, 0.5, 1)) # 6 colors
topo.colors(3, alpha=c(0, 0.5, 1)) # 9 colors
R-Version and platform:
R version 4.2.2 Patched (2022-11-10 r83330) -- "Innocent and Trusting"
Copyright (C) 2022 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
Bug or feature?
Looks like a bug to me, they should all be length 3. The reason it happens
in terrain.colors (I didn't look at the others) is that it breaks the range
into two parts, and relies on the number of values of the parameters in each
part to get the length, but passes the full alpha vector in:
terrain.colors <- function (n, alpha, rev = FALSE)
{
if ((n <- as.integer(n[1L])) > 0) {
k <- n%/%2
h <- c(4/12, 2/12, 0/12)
s <- c(1, 1, 0)
v <- c(0.65, 0.9, 0.95)
cols <- c(hsv(h = seq.int(h[1L], h[2L], length.out = k),
s = seq.int(s[1L], s[2L], length.out = k),
v = seq.int(v[1L], v[2L], length.out = k), alpha =
alpha),
hsv(h = seq.int(h[2L], h[3L], length.out = n - k + 1)[-1L],
s = seq.int(s[2L], s[3L], length.out = n - k + 1)[-1L],
v = seq.int(v[2L], v[3L], length.out = n - k + 1)[-1L],
alpha = alpha))
if(rev) rev(cols) else cols
} else character()
}
A bug fix would be to recycle alpha to the right length and only pass in
portions of it, e.g.
terrain.colors <- function (n, alpha, rev = FALSE)
{
if ((n <- as.integer(n[1L])) > 0) {
alpha <- rep_len(alpha, length.out = n)
k <- n%/%2
h <- c(4/12, 2/12, 0/12)
s <- c(1, 1, 0)
v <- c(0.65, 0.9, 0.95)
cols <- c(hsv(h = seq.int(h[1L], h[2L], length.out = k),
s = seq.int(s[1L], s[2L], length.out = k),
v = seq.int(v[1L], v[2L], length.out = k), alpha =
alpha[seq_len(k)]),
hsv(h = seq.int(h[2L], h[3L], length.out = n - k + 1)[-1L],
s = seq.int(s[2L], s[3L], length.out = n - k + 1)[-1L],
v = seq.int(v[2L], v[3L], length.out = n - k + 1)[-1L],
alpha = alpha[seq_len(n - k) + k]))
if(rev) rev(cols) else cols
} else character()
}
I'd guess the same sort of approach would fix cm.colors and topo.colors.
Duncan Murdoch
______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.