Reputation: 575
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
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
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)
Upvotes: 2