Pablo Herreros Cantis
Pablo Herreros Cantis

Reputation: 575

Select specific colors for filling a Ternary Plot

As per the documentation and tutorials provided for the Ternary package in R, the following script produces a ternary plot where each vertex of the triangle corresponds to an RGB color. I am trying to generate the same plot, but manually specifying the three colours that would be assigned to each vertex (axis).

library (Ternary)
TernaryPlot()
cols <- TernaryPointValues(rgb)
ColourTernary(cols, spectrum = NULL)

Instead of base R's RGB colours, I want to generate a ternary plot where the vertices are assigned the colours "#016699", "#769022", and "#F99C1C".

I understand that the function TernaryPointValues generates a matrix with a colour assigned to each coordinate within the Ternary Plot. Is there a way to specify the three colours other than rgb in that function?

Alternatively to the Ternary library, solutions with other R packages such as ggtern are welcome.

Upvotes: 0

Views: 66

Answers (2)

Michiel Duvekot
Michiel Duvekot

Reputation: 1881

library(Ternary)
library(colorspace)

abc <- function(red = 0, green = .4, blue = .6, alpha = 1, names = NULL, maxColorValue = 1) {
  a = red
  b = green
  c = blue
  if (a+b+c < 0 | a+b+c > 1) {
    stop("a, b, and c must sum to  1")
  }
  cols <- c("#016699", "#769022", "#F99C1C")
  #cols <- c("#ffff00", "#00ffff", "#ff00ff")
  ra = colorspace::hex2RGB(cols)[1,]@coords[1] * a
  rb = colorspace::hex2RGB(cols)[2,]@coords[1] * b
  rc = colorspace::hex2RGB(cols)[3,]@coords[1] * c
  
  ga = colorspace::hex2RGB(cols)[1,]@coords[2] * a
  gb = colorspace::hex2RGB(cols)[2,]@coords[2] * b
  gc = colorspace::hex2RGB(cols)[3,]@coords[2] * c
  
  ba = colorspace::hex2RGB(cols)[1,]@coords[3] * a
  bb = colorspace::hex2RGB(cols)[2,]@coords[3] * b
  bc = colorspace::hex2RGB(cols)[3,]@coords[3] * c
  
  r <- ra+rb+rc
  g <- ga+gb+gc
  b <- ba+bb+bc
  
  return(rgb(r, g, b, maxColorValue = 1))
}

abc_v <- Vectorize(abc)

TernaryPlot()
cols <- TernaryPointValues(rgb)
ColourTernary(cols, spectrum = NULL)

cols <- TernaryPointValues(abc_v)
ColourTernary(cols, spectrum = NULL)

Upvotes: 1

Axeman
Axeman

Reputation: 35382

We just need to write a function that interpolates across three colors. We can do the interpolation in RGB space, just like your example.

library (Ternary)

color_interp <- function(a, b, c, A = "#016699", B = "#769022", C = "#F99C1C") {
  m <- cbind(col2rgb(A), col2rgb(B), col2rgb(C)) / 256
  rgb(matrix(c(a, b, c), 1) %*% t(m))
}
color_interp_vec <- Vectorize(color_interp, c('a', 'b', 'c'))
cols <- TernaryPointValues(color_interp_vec)    

TernaryPlot()
ColourTernary(cols, spectrum = NULL)

enter image description here

Upvotes: 2

Related Questions