简体   繁体   English

R中的ggtern有什么替代品吗?

[英]Is there any alternative to ggtern in R?

Its looks like that ggtern has not been synchronised with new version of ggplot2.看起来 ggtern 尚未与新版本的 ggplot2 同步。 Therefore we can not use ggtern.因此我们不能使用ggtern。

library(ggtern)
set.seed(1)
plot <- ggtern(data = data.frame(x = runif(100),
                                 y = runif(100),
                                 z = runif(100)),
               aes(x, y, z))
plot + stat_density_tern(geom = 'polygon',
                         n         = 200,
                         aes(fill  = ..level..,
                             alpha = ..level..)) +
  geom_point() +
  theme_rgbw() +
  labs(title = "Example Density/Contour Plot")    +
  scale_fill_gradient(low = "blue",high = "red")  +
  guides(color = "none", fill = "none", alpha = "none")
Error: geom_point requires the following missing aesthetics: x and y

Does anyone have in find other options for ternary diagrams apart from ggtern in R?除了 R 中的 ggtern 之外,是否有人可以找到其他三元图选项?

Manually, you could plot the points with a function: (I used the formulas at https://en.wikipedia.org/wiki/Ternary_plot )手动,您可以使用函数绘制点:(我使用了https://en.wikipedia.org/wiki/Ternary_plot 上的公式)

I'm not familiar with the output of stat_density_tern so I'm not sure what is expected from that part.我不熟悉stat_density_tern的输出,所以我不确定该部分的预期结果。

library(tidyverse)
tern <- function(df) {
  df %>% mutate(x_pos = 0.5 * (2*y + z) / (x+y+z),
                y_pos = sqrt(3) / 2 * z / (x+y+z)) 
}

tern(plot) %>%
  ggplot(aes(x_pos, y_pos)) +
  geom_point() +
  annotate("path", x = c(0, 0.5, 1, 0), y = c(0,sqrt(3)/2,0,0)) +
  coord_equal()

在此处输入图片说明

this worked for me!这对我有用! Uninstall ggtern and ggplot2 then然后卸载ggternggplot2

install_version("ggplot2", version = "3.3.0", repos = "http://cran.us.r-project.org")

install.packages("ggtern")

library(ggtern)

I use the following script which also supports making diagrams with 4 or more corners.我使用以下脚本,它还支持制作具有 4 个或更多角的图表。 It also divides the points into colored clusters by cutting a hierarchical clustering at the height where it has 32 subtrees, and it draws a line from each point to its two nearest neighbors.它还通过在其具有 32 个子树的高度处切割层次聚类将点划分为彩色聚类,并从每个点到其最近的两个邻居画一条线。

library(tidyverse)
library(ggforce)
library(colorspace)

t=as.matrix(read.csv("https://pastebin.com/raw/1EDJJtHU",row.names=1,check.names=F))/100

fst=as.matrix(read.csv("https://pastebin.com/raw/6JmN2hRY",row.names=1))
mult=t%*%cmdscale(fst,ncol(fst)-1)

# t=cbind(t[,2]+t[,1],t[,8]+t[,9],rowSums(t[,-c(1,2,8,9)]))
# colnames(t)=c("Baltic + North_Atlantic","Siberian + East_Asian","Other")

# t=cbind(t[,2],t[,1],t[,8]+t[,9],rowSums(t[,-c(1,2,8,9)]))
# colnames(t)=c("Baltic","North_Atlantic","Siberian + East_Asian","Other")

ncorn=ncol(t)
start=ifelse(ncorn==4,.25,0)
corners=sapply(c(sin,cos),\(x)x((start+seq(0,2,,ncorn+1)[-(ncorn+1)])*pi))
corners=corners*min(2/diff(apply(corners,2,range)))
corners[,2]=corners[,2]-mean(range(corners[,2]))

xy=t%*%corners

grid=if(ncorn==3)do.call(rbind.data.frame,apply(simplify=F,rbind(c(1,2,3,2),c(1,3,2,3),c(2,1,3,1)),1,\(x)cbind(
  seq(corners[x[1],1],corners[x[2],1],,11),
  seq(corners[x[1],2],corners[x[2],2],,11),
  seq(corners[x[3],1],corners[x[4],1],,11),
  seq(corners[x[3],2],corners[x[4],2],,11)
)))else if(ncorn==4)do.call(rbind.data.frame,apply(simplify=F,rbind(c(1,2,4,3),c(1,4,2,3)),1,\(x)cbind(
  seq(corners[x[1],1],corners[x[2],1],,11),
  seq(corners[x[1],2],corners[x[2],2],,11),
  seq(corners[x[3],1],corners[x[4],1],,11),
  seq(corners[x[3],2],corners[x[4],2],,11)
)))else rbind.data.frame(cbind(corners,rbind(corners[-1,],corners[1,])),cbind(corners,matrix(colMeans(corners),ncorn,2,T)))

seg=as.data.frame(cbind(xy[rep(1:nrow(xy),each=2),],xy[apply(as.matrix(dist(mult)),1,\(x)order(x)[2:3]),]))
k=as.factor(cutree(hclust(dist(mult)),32))

set.seed(0)
hue=seq(0,360,,nlevels(k)+1)%>%head(-1)%>%sample()
pal1=hex(colorspace::HSV(hue,.6,1))
pal2=hex(colorspace::HSV(hue,.3,1))

angle=head(seq(360,0,length.out=ncorn+1),-1)
angle=ifelse(angle>90&angle<=270,angle+180,angle)

ggplot(as.data.frame(xy),aes(x=V1,y=V2))+
geom_polygon(data=as.data.frame(corners),fill="gray25")+
(if(ncorn>=5)geom_text(data=as.data.frame(corners),aes(x=1.04*V1,y=1.04*V2),label=colnames(t),size=3.2,angle=angle,color="gray85") # use rotated labels
else geom_text(data=as.data.frame(corners),aes(x=V1,y=1.03*V2),vjust=(1-corners[,2])/2,hjust=(1+corners[,1])/2,label=colnames(t),size=3.2,color="gray85"))+ # don't rotate labels
geom_segment(data=grid,aes(x=V1,y=V2,xend=V3,yend=V4),color="gray30",size=.4)+
ggforce::geom_mark_hull(aes(group=!!k,color=!!k,fill=!!k),concavity=1000,radius=unit(.15,"cm"),expand=unit(.15,"cm"),alpha=.15,size=.1)+
geom_segment(data=seg,aes(x=V1,y=V2,xend=V3,yend=V4),color="gray10",size=.25)+
geom_point(aes(color=k),size=.5)+
geom_text(aes(label=rownames(xy),color=!!k),size=2.2,vjust=-.6)+
coord_fixed(xlim=c(-1,1),ylim=c(-1,1))+
scale_fill_manual(values=pal1)+
scale_color_manual(values=pal2)+
theme(
  axis.text=element_blank(),
  axis.ticks=element_blank(),
  axis.title=element_blank(),
  legend.position="none",
  panel.background=element_rect(fill="gray20"),
  panel.grid=element_blank(),
  plot.background=element_rect(fill="gray20",color=NA,size=0),
  plot.margin=margin(0,0,0,0)
)

ggsave("1.png",width=7,height=7)

Or here's another version that uses Voronoi tesselation to plot the points ( https://ggforce.data-imaginist.com/reference/geom_delvor.html ):或者这里是另一个使用 Voronoi 镶嵌到 plot 点的版本( https://ggforce.data-imaginist.com/reference/geom_delvor.ZFC35FDC70D5FC69D2569883A822C ):

t=read.table("https://pastebin.com/raw/CeLAEiAq")
t=distinct(t[,-1]) # geom_voronoi_tile doesn't handle a large number of overlapping points
pop=t[,1]
t=as.matrix(t[,-1])

ncorn=ncol(t)
start=ifelse(ncorn==4,.25,0)
corners=sapply(c(sin,cos),\(x)x((start+seq(0,2,,ncorn+1)[-(ncorn+1)])*pi))
corners=corners*min(2/diff(apply(corners,2,range))) # resize so bigger one of width and height is 2
corners[,2]=corners[,2]-mean(range(corners[,2])) # center vertically

xy=as.data.frame(t%*%corners)

# # use a simple grid with line from each corner to center for a plot with more than 3 corners
# grid=rbind.data.frame(cbind(corners,rbind(corners[-1,],corners[1,])),cbind(corners,matrix(colMeans(corners),ncorn,2,T)))

# use a grid with 10 subdivisions per side for a triangle plot
grid=do.call(rbind.data.frame,apply(simplify=F,rbind(c(1,2,3,2),c(1,3,2,3),c(2,1,3,1)),1,\(x)cbind(
  seq(corners[x[1],1],corners[x[2],1],,11),
  seq(corners[x[1],2],corners[x[2],2],,11),
  seq(corners[x[3],1],corners[x[4],1],,11),
  seq(corners[x[3],2],corners[x[4],2],,11)
)))

centers=data.frame(aggregate(xy,list(pop),mean),row.names=1)

set.seed(0)
color=as.factor(sample(length(unique(pop))))
cl=rbind(c(60,80),c(25,95),c(30,70),c(70,50),c(60,100),c(20,50),c(15,40))
hues=max(ceiling(length(color)/nrow(cl)),8)
pal1=as.vector(apply(cl,1,\(x)hcl(seq(15,375,,hues+1)[-(hues+1)],x[1],x[2])))
pal2=as.vector(apply(cl,1,\(x)hcl(seq(15,375,,hues+1)[-(hues+1)],if(x[2]>=60).5*x[1]else .1*x[1],if(x[2]>=60).2*x[2]else 95)))

xy=xy+runif(nrow(xy)*2)/1e3 # add a small random factor to prevent errors because of overlapping points

ggplot(xy,aes(V1,V2))+
geom_segment(data=grid,aes(V1,V2,xend=V3,yend=V4),color="gray85",size=.3)+
ggforce::geom_voronoi_tile(aes(group=0,fill=color[as.factor(pop)],color=color[as.factor(pop)]),size=.07,max.radius=.055)+ # `group=0` is just an arbitrary constant
# ggrepel::geom_label_repel(data=centers,aes(V1,V2,color=color,fill=color),label=rownames(centers),max.overlaps=Inf,point.size=0,size=2.3,alpha=.8,label.r=unit(.1,"lines"),label.padding=unit(.1,"lines"),label.size=.1,box.padding=0,segment.size=.3)+
geom_label(data=centers,aes(V1,V2,color=color,fill=color),label=rownames(centers),size=2.3,alpha=.8,label.r=unit(.1,"lines"),label.padding=unit(.1,"lines"),label.size=.1)+
coord_fixed(xlim=c(-1.08,1.08),ylim=c(-1.08,1.08),expand=F)+
scale_fill_manual(values=pal1)+
scale_color_manual(values=pal2)+
theme(
  axis.text=element_blank(),
  axis.ticks=element_blank(),
  axis.title=element_blank(),
  legend.position="none",
  panel.background=element_rect(fill="white")
)

ggsave("1.png",width=7,height=7)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM