制作三元图

11

我想使用ggplot2绘制三维数据在Simplex上的投影图。我尝试使用coord_trans()在笛卡尔坐标系上进行变换,但是不知道如何准确地操作。

这是我的尝试:

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" )
任何建议都受到欢迎。非常感谢!

参见R中如何安装ggtern包 - Dante
7个回答

17

正如mmann1123所强调的,使用ggtern可以实现以下效果:

Output

只需使用以下简单的代码块即可:

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()

嗨,@Nicholas!你能否请再检查一下你的答案?我无法复制它...我认为theme_tern_bw只是theme_bw,而且点被显示在边缘下方(而不是上方)。提前致谢! - Guilherme Parreira
好的,完成了,这是早期版本的内容,请参见上文。 - Nicholas Hamilton

6

vcd包中的ternaryplot函数可以很好地从非标准化数据中制作经典的三元图:

require(vcd)
#ternaryplot takes matrices but not data frames
xM <- as.matrix(x)
ternaryplot(xM)

enter image description here


2
R软件包Ternary可以使用标准图形函数从矩阵和数据框绘制三角图。

Ternary plot created with R package Ternary

上述图表是使用以下方式创建的:
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')

1

coord_trans并不是你想象中的那样。它只会转换已经是2D的图形的x和y坐标,但你有3D数据。

自己转换数据然后再绘制图形:

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()

请注意,我已经重写了您的转换函数,使其更符合R语言的风格。此外,在aes()中不应传递像x = c(x1,x2,x3)这样的表达式。您应该将数据框中的单个变量映射到单个美学属性。

1

1

为了完整起见,您可以尝试使用经典的ade4包:

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)

1

plotrix包中的函数triax.plot()也可以绘制三元图:

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")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接