Duncan Murdoch
2023-Feb-23 11:04 UTC
[R] Palettes {grDevices} - wrong number of colors returned?
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
Achim Zeileis
2023-Feb-23 11:09 UTC
[R] Palettes {grDevices} - wrong number of colors returned?
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 at 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. >
Reasonably Related Threads
- Palettes {grDevices} - wrong number of colors returned?
- Palettes {grDevices} - wrong number of colors returned?
- need palette of topographic colors similar to topo.colors ()
- Palettes {grDevices} - wrong number of colors returned?
- Palettes {grDevices} - wrong number of colors returned?