这段代码应该给你一个接近你想要的情节。我将它与一些示例数据一起使用来创建下面给出的图。代码使用基本图形,所以应该很容易修改。这些函数创建一个对数轴从 0.01 到 100 的图。
因为绘制的值是比率,所以它们中只有两个是独立的。第三个比率可以从其他两个计算出来,因此只需要指定两个比率。
我也没有找到太多关于情节的基础计算。此代码假定通过跟踪垂直于轴的点来读取每个点的比率。例如,Ca/Mg 上 10 处的点不会是每个大约 0.3,而不是 1。
makeAxes <- function(a3, # angles of axes, assumed at 120-degree separation, value indicates positive side from 3-o'clock
d, # length of half-axis in log10-units, 2 => 0.01-100
axLab, # labels for axes
cen=c(0,0), # center of axis
ticks=T, # should tick marks be included
tickLocs=c((1:9)*10^-2,(1:9)*10^-1,(1:9),(1:9)*10^1,100), # location of tick marks
tickLen=0.05, # dimension of tick marks
endText=T # are the values at the end of axes plotted
){
# making an empty plot
plot(NA,NA
,ylim=c(-d,d)*1.5 + cen[1]
,xlim=c(-d,d)*1.5 + cen[2]
,bty='n'
,axes = F
,ylab=''
,xlab='')
# adding axis lines and notations
for(i in 1:3){
# coordinates of x and y ends of axes
# col1 = x values
matTemp <- matrix(0,2,2)
matTemp[,1] <- c(cen[1] + d*cos(a3[i]*pi/180),cen[1] - d*cos(a3[i]*pi/180))
matTemp[,2] <- c(cen[2] + d*sin(a3[i]*pi/180),cen[2] - d*sin(a3[i]*pi/180))
# plotting lines
lines(matTemp[,1],matTemp[,2])
# adding text for axes
text(x=matTemp[1,1]*1.4,y=matTemp[1,2]*1.4,
labels=axLab[i])
if(endText){
text(x=matTemp[,1]*1.1,
y=matTemp[,2]*1.1,
labels=c(10^d,10^-d),
cex=0.8
)
text(cen[1],cen[2],
lab=1,
pos=4,
cex=0.8
)
}
# adding tick marks
if(ticks){
# values are the point on the axis plus a correction to make it perpendicular
xVals1 <- cen[1] + log10(tickLocs)*cos(a3[i]*pi/180) - tickLen*sin(a3[i]*pi/180)
yVals1 <- cen[2] + log10(tickLocs)*sin(a3[i]*pi/180) - tickLen*cos(a3[i]*pi/180)
xVals2 <- cen[1] + log10(tickLocs)*cos(a3[i]*pi/180) + tickLen*sin(a3[i]*pi/180)
yVals2 <- cen[2] + log10(tickLocs)*sin(a3[i]*pi/180) + tickLen*cos(a3[i]*pi/180)
# plotting lines as tick marks
for(j in 1:length(xVals1)){
lines(c(xVals1[j],xVals2[j]),c(yVals2[j],yVals1[j]))
}
}
}
}
addPoints <- function(df, # data frame of values, must have axis columns
cen=c(0,0), # center of axis
a3 # angles of axes, assumed at 120-degree separation, value indicates positive side from 3-o'clock
){
# temporary data frame for calculations
dftemp <- df
# calculation of log values
dftemp$axis1log <- log10(dftemp$axis1)
dftemp$axis2log <- log10(dftemp$axis2)
dftemp$axis3log <- log10(dftemp$axis3)
# calculation of values along axis 1
dftemp$axis1log_xvals <- cen[1] + dftemp$axis1log*cos(a3[1]*pi/180)
dftemp$axis1log_yvals <- cen[2] + dftemp$axis1log*sin(a3[1]*pi/180)
# calculation of values along axis 2
dftemp$axis2log_xvals <- cen[1] + dftemp$axis2log*cos(a3[2]*pi/180)
dftemp$axis2log_yvals <- cen[2] + dftemp$axis2log*sin(a3[2]*pi/180)
# slope calcuation
dftemp$axis1_perp <- sin((a3[1]+90)*pi/180)/cos((a3[1]+90)*pi/180)
dftemp$axis2_perp <- sin((a3[2]+90)*pi/180)/cos((a3[2]+90)*pi/180)
# intersection points
# y1 = ax1 + c
# y2 = bx2 + d
a <- dftemp$axis1_perp
b <- dftemp$axis2_perp
c <- dftemp$axis1log_yvals - dftemp$axis1_perp*dftemp$axis1log_xvals
d <- dftemp$axis2log_yvals - dftemp$axis2_perp*dftemp$axis2log_xvals
dftemp$intersectx <- (d-c)/(a-b)
dftemp$intersecty <- a*(d-c)/(a-b)+c
points(dftemp$intersectx
,dftemp$intersecty
,pch=19 # plotting symbol
,col='gray48' # colors of points
,cex=1.2 # multiplier for plotting symbols
)
}
# example data
labs <- c("a","b","c","d","e","f","g")
k <- c(150, 100, 3000, 3500, 10, 10, 30)
ca <- c(500, 120, 350, 100, 10, 10, 30)
mg <- c(50, 450, 220, 350, 10, 100, 60)
# conversion into data frame
dataPlot <- as.data.frame(list('labs'=labs,'k'=k,'ca'=ca,'mg'=mg)
# calcuations with data frame
dataPlot$axis1 <- dataPlot$ca/dataPlot$mg
dataPlot$axis2 <- dataPlot$k/dataPlot$ca
dataPlot$axis3 <- dataPlot$mg/dataPlot$k
# making axes
makeAxes(a3=c(90,-30,210),
d=2,
axLab=c("Ca/Mg", "K/Ca", "Mg/K" ))
# adding points
addPoints(df=dataPlot,
a3=c(90,-30,210))