This code should give you a plot close to what you desire. I used it with some example data to create the plot given below. The code uses base graphics, so it should be simple to modify. The functions create a plot with log axes from 0.01 to 100.
Because the plotted values are ratios, the only two of them are independent. The third ratio can be calculated from the other two, so only specifying two ratios is required.
I didn't find much on the underlying calculations for the plot either. This code assumes that the ratios for each point are read by tracing the point perpendicular to the axes. For example, the point at 10 on Ca/Mg will not be about 0.3 for each, not 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))