[R] Palettes {grDevices} - wrong number of colors returned?
Achim Zeileis
Ach|m@Ze||e|@ @end|ng |rom u|bk@@c@@t
Thu Feb 23 12:09:14 CET 2023
Duncan,
thanks for your feedback. I just received your response after sending out
mine. You came to the same conclusion. Should I prepare a patch and send
it to you so that you can also have a look? Or view Bugzilla?
Best wishes,
Achim
On Thu, 23 Feb 2023, Duncan Murdoch wrote:
> 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 using 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.
>
More information about the R-help
mailing list