Re: [R] Soil texture triangle in R?

2005-05-28 Thread Sander Oom

Hi Jim,

Your email was classified as spam, so I missed it previously. 
Unfortunately you did not send a cc to the R-help list. I send a cc to 
the mailing list now, so all code gets archived.


Thanks for the improvements on your function! It seems that drawing the 
ternary graph and the points with the generic plot functions works well. 
Makes the function less dependent on other packages!


Will merge the two functions into one and post it back to the mailing 
list! Then the graph might be ready for the graph gallery!


Thanks,

Sander.


Jim Lemon wrote:
 Sander Oom wrote:
 Hi Jim,

 This looks impressive! It gives me the 'background' graph. However,
 I'm not sure how I can use this function to plot my soil texture
 values! Can you explain?

 I would like to be able to plot my soil texture samples in the same
 graph as the one your function plots.

 Yes, that's just the background figure for which you attached the link.
 I was unsure of how you were going to use this, that is, do you just
 place a symbol for each soil sample? Aha! Just read your latest email
 and I think that's what you want.

 Let's say you have one or more soil samples with the proportions of
 clay, sand and silt.

 sample1-c(0.1,0.4,0.5)
 sample2-c(0.2,0.5,0.3)
 soil.samples-rbind(sample1,sample2)
 colnames(soil.samples)-c(clay,sand,silt)

 This more complicated function allows you to overlay colored points
 representing soil samples on either an empty triangle, a gridded
 triangle or a triangle with soil type names. It also has an optional
 legend.

 par(ask=TRUE)
 soil.triangle(soil.samples)
 soil.triangle(soil.samples,show.grid=TRUE)
 soil.triangle(soil.samples,soil.names=TRUE,legend=TRUE)
 par(ask=FALSE)

 Jim

 

 soil.triangle-function(soilprop,pch=NULL,col=NULL,soil.names=FALSE,
  show.grid=FALSE,show.legend=FALSE) {
  if(missing(soilprop))
   stop(Usage: 
soil.triangle(soilprop,pch=NULL,col=NULL,soil.names=FALSE,show.grid=FALSE))

  if(!is.matrix(soilprop))
   stop(soilprop must be a matrix with at least three columns and one 
row.)

  if(any(soilprop  1) || any(soilprop  0))
   stop(All soil proportions must be between zero and one.)
  if(any(abs(rowSums(soilprop)-1)  0.01))
   warning(At least one set of soil proportions does not equal one.)
  oldpar-par(no.readonly=TRUE)
  plot(0:1,type=n,axes=FALSE,xlim=c(0,1.1),ylim=c(0,1),
   main=Soil Triangle,xlab=,ylab=)
  # first draw the triangle
  x1-c(0,0,0.5)
  sin60-sin(pi/3)
  x2-c(1,0.5,1)
  y1-c(0,0,sin60)
  y2-c(0,sin60,0)
  segments(x1,y1,x2,y2)
  # now the bottom internal ticks
  bx1-seq(0.1,0.9,by=0.1)
  bx2-bx1-0.01
  by1-rep(0,9)
  by2-rep(0.02*sin60,9)
  segments(bx1,by1,bx2,by2)
  text(bx1,by1-0.03,as.character(rev(seq(10,90,by=10
  # now the left internal ticks
  ly1-bx1*sin60
  lx1-bx1*0.5
  lx2-lx1+0.02
  ly2-ly1
  segments(lx1,ly1,lx2,ly2)
  text(lx1-0.03,ly1,as.character(seq(10,90,by=10)))
  # right internal ticks
  rx1-rev(lx1+0.5-0.01)
  rx2-rx1+0.01
  ry1-ly1-0.02*sin60
  ry2-ly2
  segments(rx1,ry1,rx2,ry2)
  if(show.grid) {
   segments(bx2,by2,lx1,ly1,lty=3)
   segments(lx2,ly2,rx2,ry2,lty=3)
   segments(rev(rx1),rev(ry1),bx1,by1,lty=3)
  }
  text(rx2+0.03,ry1+0.025,as.character(rev(seq(10,90,by=10
  text(0.5,0.9,100% clay)
  par(xpd=TRUE)
  text(-0.1,0,100% sand)
  text(1.1,0,100% loam)
  text(0.07,0.43,percent clay)
  text(0.93,0.43,percent silt)
  text(0.5,-0.1,percent sand)
  if(soil.names) {
   # boundary of clay with extensions
   x1-c(0.275,0.35,0.6)
   x2-c(0.4,0.79,0.7)
   y1-c(0.55*sin60,0.41*sin60,0.41*sin60)
   y2-c(0.285*sin60,0.41*sin60,0.6*sin60)
   segments(x1,y1,x2,y2)
   # lower bound of clay loam  silty divider
   x1-c(0.4,0.68)
   x2-c(0.86,0.6)
   y1-c(0.285*sin60,0.285*sin60)
   y2-c(0.285*sin60,0.41*sin60)
   segments(x1,y1,x2,y2)
   x1-c(0.185,0.1,0.37)
   x2-c(0.36,0.37,0.4)
   y1-c(0.37*sin60,0.2*sin60,0.2*sin60)
   y2-c(0.37*sin60,0.2*sin60,0.285*sin60)
   segments(x1,y1,x2,y2)
   # sand corner
   x1-c(0.05,0.075)
   x2-c(0.12,0.3)
   y1-c(0.1*sin60,0.15*sin60)
   y2-c(0,0)
   segments(x1,y1,x2,y2)
   x1-c(0.37,0.42,0.5,0.8,0.86)
   x2-c(0.42,0.54,0.65,0.86,0.94)
   y1-c(0.2*sin60,0.08*sin60,0,0,0.12*sin60)
   y2-c(0.08*sin60,0.08*sin60,0.285*sin60,0.12*sin60,0.12*sin60)
   segments(x1,y1,x2,y2)
   text(0.5,0.57,Clay)
   text(0.7,0.49*sin60,Silty)
   text(0.7,0.44*sin60,clay)
   text(0.73,0.37*sin60,Silty clay)
   text(0.73,0.33*sin60,loam)
   text(0.5,0.35*sin60,Clay loam)
   text(0.27,0.43*sin60,Sandy)
   text(0.27,0.39*sin60,clay)
   text(0.27,0.3*sin60,Sandy clay)
   text(0.27,0.26*sin60,loam)
   text(0.25,0.13*sin60,Sandy loam)
   text(0.13,0.075*sin60,Loamy)
   text(0.15,0.035*sin60,sand)
   text(0.055,0.021,Sand)
   text(0.49,0.18*sin60,Loam)
   text(0.72,0.15*sin60,Silt loam)
   text(0.9,0.06*sin60,Silt)
  }
  if(is.null(pch)) pch-1:nrow(soilprop)
  if(is.null(col)) col-2:(nrow(soilprop)+1)
  

Re: [R] Soil texture triangle in R?

2005-05-28 Thread Sander Oom

Dear R users,

Please find attached a new plot function, plot.soiltexture, to plot soil 
texture data on a triangular plot with an optional backdrop of the USDA 
soil texture classification, written by Jim Lemon and me.


I tried to write the function and documentation confirm the R 
conventions. However, this is a new experience for me, so any comments 
and suggestions are welcome!


I tried to find a suitable package for the plot function, but none are 
obvious.


I have approached Todd Skaggs to ask permission to include sample data 
from the paper:
Skaggs, T.H., L.M. Arya, P.J. Shouse, and B.P. Mohanty. 2001. Estimating 
particle-size distribution from limited soil texture data. Soil Sci. 
Soc. Am. J., 65:1038-1044.

http://soil.scijournals.org/cgi/content/full/65/4/1038

Things still to do:
- rotate axis labels;
- rotate axis tick labels
- provide option to plot ticks inside or outside plot area.

Thus making it look like:
http://soils.usda.gov/technical/manual/images/fig3-16_large.jpg
or
http://soil.scijournals.org/content/vol65/issue4/images/large/1038f2.jpeg

Enjoy,

Sander.
# Description
# 
# Plots soil texture data on an equilateral triangle. Provides the option to
# draw the USDA soil texture classification as a backdrop.
# 
# Usage
# 
# plot.soiltexture - function(soiltexture, main=NULL, pch=1, col=black,
#   soil.names=TRUE, soil.lines=TRUE, show.points=TRUE,
#   show.clabels=FALSE, show.grid=FALSE, show.legend=FALSE, 
#   col.names=grey, col.lines=grey, bg.pch=white,
#   col.grid=grey, lty.grid=3)
# 
# Arguments
#
# soiltexture   a matrix with three columns (see details)
# main  title of the plot; defaults to NULL
# pch   variable or vector containing point symbols; defaults to 1
# col   variable or vector containing point colour; defaults to black
# soil.namesa logical value indicating whether the soil texture class names 
are printed; defaults to TRUE
# soil.linesa logical value indicating whether the soil texture class 
division lines are plotted; defaults to TRUE
# show.points   a logical value indicating whether the soil sample points are 
plotted; defaults to TRUE
# show.clabels  a logical value indicating whether the corner labels for 100% 
sand, silt and clay are printed; defaults to FALSE
# show.grid a logical value indicating whether the fixed grid is plotted; 
defaults to FALSE
# show.legend   a logical value indicating whether the legendis plotted; 
defaults to FALSE
# col.names colour of the soil texture class names; defaults to grey
# col.lines colour of the soil texture class division lines; defaults to 
grey
# bg.pchcolour of the points symbols when pch 21:25 are used; defaults 
to white
# col.grid  colour of the fixed grid; defaults to grey
# lty.grid  line style for the fixed grid; defaults to 3
#
# Details
# 
# The object soiltexture must be a matrix with at least three columns and one 
row.
# Columns should contain data for Sand, Silt, and Clay, in that order! Sand, 
Silt, 
# and Clay should be expressed in proportions between 0 and 1.
#
# The soil sample points' coordinates are calculated using simple trigonometry.
# Thus, the coordinates of a point P(Sand,Silt,Clay), where Sand + Silt + Clay 
= 1,
# are: P(1-Sand+(Sand-(1-Silt))*0.5, Clay*sin(pi/3))
#
# Author(s)
# 
# Jim Lemon
# Sander Oom
# 
# References
# 
# Soil Survey Division Staff. 1993. Soil survey manual. Soil Conservation 
Service.
# U.S. Department of Agriculture Handbook 18.
#
# Examples
# 
# # some triangular data
# library(MASS)
# tmp-(Skye/100)
# # colnames choosen to be consistent with MASS-fig4.4
# colnames(tmp) - c(Clay,Sand,Silt)
# soiltexture - cbind(tmp$Sand,tmp$Silt,tmp$Clay)
# # the USDA backdrop in black
# plot.soiltexture(NULL, show.points=FALSE, col.names=black, 
col.lines=black)
# # the USDA backdrop and a fixed grid in grey
# plot.soiltexture(NULL, show.points=FALSE, show.grid=TRUE)
# # soil sample points with backdrop in grey
# plot.soiltexture(soiltexture)

plot.soiltexture - function(soiltexture, main=Soil Texture Plot, pch=1, 
col=black,
  soil.names=TRUE, soil.lines=TRUE,
  show.points=TRUE, show.clabels=FALSE, show.grid=FALSE, show.legend=FALSE, 
  col.names=grey, col.lines=grey, bg.pch=white,
  col.grid=grey, lty.grid=3) {
  
  if(show.points) {
## error checking
if(missing(soiltexture))
  stop(Usage: plot.soiltexture(soiltexture, pch=NULL, col=NULL, 
soil.names=FALSE, show.grid=FALSE))
if(!is.matrix(soiltexture))
  stop(Object soiltexture must be a matrix with at least three columns 
(for Sand, Silt, and Clay) and one row.)
if(any(soiltexture  1) || any(soiltexture  0))
  stop(All soil texture proportions must be between zero and one.)
if(any(abs(rowSums(soiltexture)-1)  0.01))
  warning(At least one set of soil texture proportions does not equal 
one.)
  }
  
  oldpar-par(no.readonly=TRUE)
  sin60-sin(pi/3)
  par(xpd=TRUE) 

  # create empty canvas to draw
  

[R] Soil texture triangle in R?

2005-05-27 Thread Sander Oom

Dear R users,

has anybody made an attempt to create the soil texture triangle graph in 
R? For an example see here:


http://www.teachingkate.org/images/soiltria.gif

I would like to get the lines in black and texture labels in gray to 
allow for plotting my texture results on top.


Any examples or suggestions are very welcome!

Thanks in advance,

Sander.

--

Dr Sander P. Oom
Animal, Plant and Environmental Sciences,
University of the Witwatersrand
Private Bag 3, Wits 2050, South Africa
Tel (work)  +27 (0)11 717 64 04
Tel (home)  +27 (0)18 297 44 51
Fax +27 (0)18 299 24 64
Email   [EMAIL PROTECTED]
Web www.oomvanlieshout.net/sander

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] Soil texture triangle in R?

2005-05-27 Thread Sander Oom

Right,

Got the data points plotted on top of the soil texture background, 
thanks to Jim and ternaryplot{vcd}! See code below.


Now there is some fine tuning to do, as it should really look like this 
graph:

http://soil.scijournals.org/content/vol65/issue4/images/large/1038f2.jpeg

Things to do:
- rotate axis labels;
- correct small errors in class divisions;
- correct the partial covering of the bottom tick labels;
- rotate ticks in order to simplify viewing the graph.

Any help still appreciated!

Cheers,

Sander.


soil.triangle - function() {
  oldpar - par(no.readonly=TRUE)
  ## now the bottom internal ticks
  x1-seq(0.1,0.9,by=0.1)
  x2-x1
  y1-rep(0,9)
  y2-rep(-0.02,9)
  segments(x1,y1,x2,y2)
  text(x1,y1-0.03,as.character(rev(seq(10,90,by=10 #, cex=0.8)
  ## now the left internal ticks
  y1-x1*sin60
  x1-x1*0.5
  x2-x1+0.02*sin60
  y2-y1-0.02*0.5
  segments(x1,y1,x2,y2)
  text(x1-0.03,y1+0.015,as.character(seq(10,90,by=10)))
  ## now the right internal ticks
  x1-rev(x1+0.5-0.02*sin60)
  x2-x1+0.02*sin60
  segments(x1,y2,x2,y1)
  text(x2+0.03,y1+0.015,as.character(rev(seq(10,90,by=10
  ## the labels at the corners
  par(xpd=TRUE)
#   text(0.5,0.9,100% clay)
#   text(-0.1,0,100% sand)
#   text(1.1,0,100% loam)
  text(0.09,0.43,% Clay)
  text(0.90,0.43,% Silt)
  text(0.5,-0.1,% Sand)
  # boundary of clay with extensions
  x1-c(0.275,0.35,0.6)
  x2-c(0.4,0.79,0.7)
  y1-c(0.55*sin60,0.41*sin60,0.41*sin60)
  y2-c(0.285*sin60,0.41*sin60,0.6*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.5,0.57,Clay, col=grey)
  # lower bound of clay loam  silty divider
  x1-c(0.4,0.68)
  x2-c(0.86,0.6)
  y1-c(0.285*sin60,0.285*sin60)
  y2-c(0.285*sin60,0.41*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.7,0.49*sin60,Silty, col=grey)
  text(0.7,0.44*sin60,clay, col=grey)
  text(0.73,0.37*sin60,Silty clay, col=grey)
  text(0.73,0.33*sin60,loam, col=grey)
  text(0.5,0.35*sin60,Clay loam, col=grey)
  x1-c(0.185,0.1,0.37)
  x2-c(0.36,0.37,0.4)
  y1-c(0.37*sin60,0.2*sin60,0.2*sin60)
  y2-c(0.37*sin60,0.2*sin60,0.285*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.27,0.43*sin60,Sandy, col=grey)
  text(0.27,0.39*sin60,clay, col=grey)
  text(0.27,0.3*sin60,Sandy clay, col=grey)
  text(0.27,0.26*sin60,loam, col=grey)
  # sand corner
  x1-c(0.05,0.075)
  x2-c(0.12,0.3)
  y1-c(0.1*sin60,0.15*sin60)
  y2-c(0,0)
  segments(x1,y1,x2,y2, col=grey)
  text(0.25,0.13*sin60,Sandy loam, col=grey)
  text(0.13,0.075*sin60,Loamy, col=grey)
  text(0.15,0.035*sin60,sand, col=grey)
  text(0.055,0.021,Sand, col=grey)
  x1-c(0.37,0.42,0.5,0.8,0.86)
  x2-c(0.42,0.54,0.65,0.86,0.94)
  y1-c(0.2*sin60,0.08*sin60,0,0,0.12*sin60)
  y2-c(0.08*sin60,0.08*sin60,0.285*sin60,0.12*sin60,0.12*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.49,0.18*sin60,Loam, col=grey)
  text(0.72,0.15*sin60,Silt loam, col=grey)
  text(0.9,0.06*sin60,Silt, col=grey)
  par(oldpar)
}

tmp - array(dim=c(10,3))
tmp[,1] - abs(rnorm(10)*20)
tmp[,2] - abs(rnorm(10)*10)
tmp[,3] - 100-tmp[,1]-tmp[,2]
tmp

library(vcd)
## Mark groups
ternaryplot(tmp,
  grid=FALSE,
  dimnames.position = none,
  pch=1, col=black,
  scale=1, main=NULL,
  prop.size=FALSE,
  )
soil.triangle()


Sander Oom wrote:

Hi Jim,

This looks impressive! It gives me the 'background' graph. However, I'm 
not sure how I can use this function to plot my soil texture values! Can 
you explain?


I would like to be able to plot my soil texture samples in the same 
graph as the one your function plots.


Maybe I should try to figure out how to replicate your code inside a 
ternaryplot{vcd} call.


Cheers,

Sander.

Jim Lemon wrote:
  Sander Oom wrote:
  Dear R users,
 
  has anybody made an attempt to create the soil texture triangle graph
  in R? For an example see here:
 
  http://www.teachingkate.org/images/soiltria.gif
 
  I would like to get the lines in black and texture labels in gray to
  allow for plotting my texture results on top.
 
  Any examples or suggestions are very welcome!
 
  It's not too hard to write a plot function to do this, but I'm not sure
  whether this will be what you want. Anyway, try it out.
 
  Jim
 
  
 
  soil.triangle-function() {
   oldpar-par(no.readonly=TRUE)
   plot(0:1,type=n,axes=FALSE,xlim=c(0,1.1),ylim=c(0,1),
main=Soil Triangle,xlab=,ylab=)
   # first draw the triangle
   x1-c(0,0,0.5)
   sin60-sin(pi/3)
   x2-c(1,0.5,1)
   y1-c(0,0,sin60)
   y2-c(0,sin60,0)
   segments(x1,y1,x2,y2)
   # now the bottom internal ticks
   x1-seq(0.1,0.9,by=0.1)
   x2-x1
   y1-rep(0,9)
   y2-rep(0.02,9)
   segments(x1,y1,x2,y2)
   text(x1,y1-0.03,as.character(rev(seq(10,90,by=10
   # now the left internal ticks
   y1-x1*sin60
   x1-x1*0.5
   x2-x1+0.02*sin60
   y2-y1-0.02*0.5
   segments(x1,y1,x2,y2)
   text(x1-0.03,y1+0.015,as.character(seq(10,90,by=10)))
   x1-rev(x1+0.5-0.02*sin60)
   x2-x1+0.02*sin60
   segments(x1,y2,x2,y1)
   text(x2+0.03,y1+0.015,as.character(rev(seq(10,90,by=10
   text

Re: [R] Soil texture triangle in R?

2005-05-27 Thread Sander Oom
(0.4,0.68)
  x2-c(0.86,0.6)
  y1-c(0.285*sin60,0.285*sin60)
  y2-c(0.285*sin60,0.41*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.7,0.49*sin60,Silty, col=grey)
  text(0.7,0.44*sin60,clay, col=grey)
  text(0.73,0.37*sin60,Silty clay, col=grey)
  text(0.73,0.33*sin60,loam, col=grey)
  text(0.5,0.35*sin60,Clay loam, col=grey)
  x1-c(0.185,0.1,0.37)
  x2-c(0.36,0.37,0.4)
  y1-c(0.37*sin60,0.2*sin60,0.2*sin60)
  y2-c(0.37*sin60,0.2*sin60,0.285*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.27,0.43*sin60,Sandy, col=grey)
  text(0.27,0.39*sin60,clay, col=grey)
  text(0.27,0.3*sin60,Sandy clay, col=grey)
  text(0.27,0.26*sin60,loam, col=grey)
  # sand corner
  x1-c(0.05,0.075)
  x2-c(0.12,0.3)
  y1-c(0.1*sin60,0.15*sin60)
  y2-c(0,0)
  segments(x1,y1,x2,y2, col=grey)
  text(0.25,0.13*sin60,Sandy loam, col=grey)
  text(0.13,0.075*sin60,Loamy, col=grey)
  text(0.15,0.035*sin60,sand, col=grey)
  text(0.055,0.021,Sand, col=grey)
  x1-c(0.37,0.42,0.5,0.8,0.86)
  x2-c(0.42,0.54,0.65,0.86,0.94)
  y1-c(0.2*sin60,0.08*sin60,0,0,0.12*sin60)
  y2-c(0.08*sin60,0.08*sin60,0.285*sin60,0.12*sin60,0.12*sin60)
  segments(x1,y1,x2,y2, col=grey)
  text(0.49,0.18*sin60,Loam, col=grey)
  text(0.72,0.15*sin60,Silt loam, col=grey)
  text(0.9,0.06*sin60,Silt, col=grey)
  par(oldpar)
}

tmp - array(dim=c(10,3))
tmp[,1] - abs(rnorm(10)*20)
tmp[,2] - abs(rnorm(10)*10)
tmp[,3] - 100-tmp[,1]-tmp[,2]
tmp

library(vcd)
## Mark groups
ternaryplot(tmp,
  grid=FALSE,
  dimnames.position = none,
  pch=1, col=black,
  scale=1, main=NULL,
  prop.size=FALSE,
  )
soil.triangle()


Sander Oom wrote:

Hi Jim,

This looks impressive! It gives me the 'background' graph. However, 
I'm not sure how I can use this function to plot my soil texture 
values! Can you explain?


I would like to be able to plot my soil texture samples in the same 
graph as the one your function plots.


Maybe I should try to figure out how to replicate your code inside a 
ternaryplot{vcd} call.


Cheers,

Sander.

Jim Lemon wrote:
  Sander Oom wrote:
  Dear R users,
 
  has anybody made an attempt to create the soil texture triangle graph
  in R? For an example see here:
 
  http://www.teachingkate.org/images/soiltria.gif
 
  I would like to get the lines in black and texture labels in gray to
  allow for plotting my texture results on top.
 
  Any examples or suggestions are very welcome!
 
  It's not too hard to write a plot function to do this, but I'm not 
sure

  whether this will be what you want. Anyway, try it out.
 
  Jim
 
  


 
  soil.triangle-function() {
   oldpar-par(no.readonly=TRUE)
   plot(0:1,type=n,axes=FALSE,xlim=c(0,1.1),ylim=c(0,1),
main=Soil Triangle,xlab=,ylab=)
   # first draw the triangle
   x1-c(0,0,0.5)
   sin60-sin(pi/3)
   x2-c(1,0.5,1)
   y1-c(0,0,sin60)
   y2-c(0,sin60,0)
   segments(x1,y1,x2,y2)
   # now the bottom internal ticks
   x1-seq(0.1,0.9,by=0.1)
   x2-x1
   y1-rep(0,9)
   y2-rep(0.02,9)
   segments(x1,y1,x2,y2)
   text(x1,y1-0.03,as.character(rev(seq(10,90,by=10
   # now the left internal ticks
   y1-x1*sin60
   x1-x1*0.5
   x2-x1+0.02*sin60
   y2-y1-0.02*0.5
   segments(x1,y1,x2,y2)
   text(x1-0.03,y1+0.015,as.character(seq(10,90,by=10)))
   x1-rev(x1+0.5-0.02*sin60)
   x2-x1+0.02*sin60
   segments(x1,y2,x2,y1)
   text(x2+0.03,y1+0.015,as.character(rev(seq(10,90,by=10
   text(0.5,0.9,100% clay)
   par(xpd=TRUE)
   text(-0.1,0,100% sand)
   text(1.1,0,100% loam)
   text(0.07,0.43,percent clay)
   text(0.93,0.43,percent silt)
   text(0.5,-0.1,percent sand)
   # boundary of clay with extensions
   x1-c(0.275,0.35,0.6)
   x2-c(0.4,0.79,0.7)
   y1-c(0.55*sin60,0.41*sin60,0.41*sin60)
   y2-c(0.285*sin60,0.41*sin60,0.6*sin60)
   segments(x1,y1,x2,y2)
   text(0.5,0.57,Clay)
   # lower bound of clay loam  silty divider
   x1-c(0.4,0.68)
   x2-c(0.86,0.6)
   y1-c(0.285*sin60,0.285*sin60)
   y2-c(0.285*sin60,0.41*sin60)
   segments(x1,y1,x2,y2)
   text(0.7,0.49*sin60,Silty)
   text(0.7,0.44*sin60,clay)
   text(0.73,0.37*sin60,Silty clay)
   text(0.73,0.33*sin60,loam)
   text(0.5,0.35*sin60,Clay loam)
   x1-c(0.185,0.1,0.37)
   x2-c(0.36,0.37,0.4)
   y1-c(0.37*sin60,0.2*sin60,0.2*sin60)
   y2-c(0.37*sin60,0.2*sin60,0.285*sin60)
   segments(x1,y1,x2,y2)
   text(0.27,0.43*sin60,Sandy)
   text(0.27,0.39*sin60,clay)
   text(0.27,0.3*sin60,Sandy clay)
   text(0.27,0.26*sin60,loam)
   # sand corner
   x1-c(0.05,0.075)
   x2-c(0.12,0.3)
   y1-c(0.1*sin60,0.15*sin60)
   y2-c(0,0)
   segments(x1,y1,x2,y2)
   text(0.25,0.13*sin60,Sandy loam)
   text(0.13,0.075*sin60,Loamy)
   text(0.15,0.035*sin60,sand)
   text(0.055,0.021,Sand)
   x1-c(0.37,0.42,0.5,0.8,0.86)
   x2-c(0.42,0.54,0.65,0.86,0.94)
   y1-c(0.2*sin60,0.08*sin60,0,0,0.12*sin60)
   y2-c(0.08*sin60,0.08*sin60,0.285*sin60,0.12*sin60,0.12*sin60)
   segments(x1,y1,x2,y2)
   text(0.49,0.18*sin60,Loam)
   text(0.72,0.15*sin60,Silt loam)
   text(0.9,0.06*sin60,Silt)
   par(oldpar