Reputation: 7113
I want to plot the projection of 3-dimensional data on their simplex using ggplot2. I thought I could manage the transformation on cartesian coordinates using coord_trans()
, but do not know how to do it exactly.
This is what I tried:
simplex.y <- function( x1, x2, x3 ) {
return( sqrt(0.75) * x3 / (x1+x2+x3) )
}
simplex.x <- function( x1, x2, x3 ) {
return( (x2 + 0.5 * x3) / (x1+x2+x3) )
}
x <- data.frame(
x1 = c( 0, 0, 1, 0.1, 0.6, 0.2 ),
x2 = c( 0, 1, 0, 0.3, 0.2, 0.8 ),
x3 = c( 1, 0, 0, 0.6, 0.2, 0.0 )
)
require(ggplot2)
ggplot( data = x, aes( x = c(x1, x2, x3), y = c(x1, x2, x3)) ) +
geom_point() +
coord_trans( x="simplex.x", y="simplex.y" )
Any suggestions are appreciated. Many thanks!
Upvotes: 13
Views: 16287
Reputation: 21
The function triax.plot()
, from the plotrix
package also draws ternary plots:
require(plotrix)
x <- data.frame(
x1 = c( 0, 0, 1, 0.1, 0.6, 0.2 ),
x2 = c( 0, 1, 0, 0.3, 0.2, 0.8 ),
x3 = c( 1, 0, 0, 0.6, 0.2, 0.0 )
)
triax.plot(x, pch=16,col.symbols="red")
Upvotes: 1
Reputation: 10526
As mmann1123 highlighted, using ggtern, the following can be achieved:
With the following simple codeblock:
x <- data.frame(
x1 = c( 0, 0, 1, 0.1, 0.6, 0.2 ),
x2 = c( 0, 1, 0, 0.3, 0.2, 0.8 ),
x3 = c( 1, 0, 0, 0.6, 0.2, 0.0 )
)
ggtern(data=x,aes(x2,x1,x3)) +
geom_mask() +
geom_point(fill="red",shape=21,size=4) +
theme_bw() +
theme_showarrows() +
theme_clockwise()
Upvotes: 19
Reputation: 771
For completeness, you can try the good old ade4
package:
x <- data.frame(
x1 = c( 0, 0, 1, 0.1, 0.6, 0.2 ),
x2 = c( 0, 1, 0, 0.3, 0.2, 0.8 ),
x3 = c( 1, 0, 0, 0.6, 0.2, 0.0 )
)
require(ade4)
triangle.plot(x)
Upvotes: 1
Reputation: 4077
The R package Ternary produces ternary plots from matrices and data.frames using the standard graphics functions.
The above plot is created with:
x <- data.frame(
x1 = c( 0, 0, 1, 0.1, 0.6, 0.2 ),
x2 = c( 0, 1, 0, 0.3, 0.2, 0.8 ),
x3 = c( 1, 0, 0, 0.6, 0.2, 0.0 )
)
TernaryPlot()
TernaryPoints(x, col='red')
Upvotes: 2
Reputation: 5295
Use the ggtern library you can read about it here. http://ggtern.com/
Upvotes: 1
Reputation: 16617
The ternaryplot function in the vcd package does a nice job of making classical ternary plots from non-normalized data:
require(vcd)
#ternaryplot takes matrices but not data frames
xM <- as.matrix(x)
ternaryplot(xM)
Upvotes: 7
Reputation: 173667
coord_trans
doesn't do what you seem to think it does. It will transform the x and y coordinates of a plot that's already 2D, but you have 3D data.
Just transform the data yourself and then plot it:
simplex.y <- function(x) {
return( sqrt(0.75) * x[3] / sum(x) )
}
simplex.x <- function(x) {
return( (x[2] + 0.5 * x[3]) / sum(x) )
}
x <- data.frame(
x1 = c( 0, 0, 1, 0.1, 0.6, 0.2 ),
x2 = c( 0, 1, 0, 0.3, 0.2, 0.8 ),
x3 = c( 1, 0, 0, 0.6, 0.2, 0.0 )
)
newDat <- data.frame(x = apply(x,1,simplex.x),
y = apply(x,1,simplex.y))
ggplot(newDat,aes(x = x,y = y)) +
geom_point()
Note that I rewrote your transformation functions to be more R-like. Also, you shouldn't be passing expressions like x = c(x1,x2,x3)
inside of aes()
. You map a single variable in your data frame to a single aesthetic.
Upvotes: 1