1
- # Create a ternary plot from a data frame
2
- ternaryPlot <- function (x , plotPoints = TRUE , labels = c(" " , " " , " " ), grid = TRUE , increment = 20 , ... ) {
3
- ternaryTriangle()
4
- ternaryLabels(labels [1 ], labels [2 ], labels [3 ])
5
- if (grid == TRUE ) {
6
- ternaryGrid(increment )
7
- }
8
- if (plotPoints == TRUE ) {
9
- ternaryPoints(x , ... )
10
- }
11
- }
12
-
13
- # Add points from a data frame to an existing ternary plot
14
- ternaryPoints <- function (x , ... ) {
15
- x <- validatedTernaryPoints(x )
16
- coords <- cartesianFromTernary(x [, 1 ], x [, 2 ], x [, 3 ])
17
- graphics :: points(coords $ x , coords $ y , ... )
18
- }
19
-
20
- # Add a line segment to an existing ternary plot
21
- # Color and line type may be added as additional arguments
22
- ternarySegment <- function (x0 , x1 , ... ) {
23
- # x0 and x1 are vectors of the endpoint ternary coordinates
24
- coords0 <- cartesianFromTernary(x0 [1 ], x0 [2 ], x0 [3 ])
25
- coords1 <- cartesianFromTernary(x1 [1 ], x1 [2 ], x1 [3 ])
26
- graphics :: segments(coords0 $ x , coords0 $ y , coords1 $ x , coords1 $ y , ... )
27
- }
28
-
29
- # Add a polygon to an existing ternary plot
30
- # Color may be added as an additional argument
31
- ternaryPolygon <- function (x , ... ) {
32
- nPoints <- nrow(x )
33
- xCoord <- vector(mode = " numeric" , length = nPoints )
34
- yCoord <- vector(mode = " numeric" , length = nPoints )
35
- for (i in 1 : nPoints ) {
36
- coords <- cartesianFromTernary(x [i , 1 ], x [i , 2 ], x [i , 3 ])
37
- xCoord [i ] <- coords $ x
38
- yCoord [i ] <- coords $ y
39
- }
40
- graphics :: polygon(xCoord , yCoord , ... )
41
- }
42
-
43
- # Add text to an existing ternary plot
44
- # Text styling may be added as additional arguments
45
- ternaryText <- function (x , label = " " , ... ) {
46
- coords <- cartesianFromTernary(x [1 ], x [2 ], x [3 ])
47
- graphics :: text(coords $ x , coords $ y , label = label , ... )
48
- }
49
-
50
- # ---------------------------------------------------------------------------------------
51
- # The following functions are called by ternaryPlot() and generally will not need to be
52
- # called directly
53
-
54
- # # Plotting primitives -------------------------------------------------------------------
55
- ternaryTriangle <- function () {
56
- top <- cartesianFromTernary(100 , 0 , 0 )
57
- left <- cartesianFromTernary(0 , 100 , 0 )
58
- right <- cartesianFromTernary(0 , 0 , 100 )
59
- lim <- c(- 1.1 , 1.1 )
60
- graphics :: plot(top $ x , top $ y , xlim = lim , ylim = lim , type = " n" , asp = 1 , axes = FALSE , xlab = " " , ylab = " " )
61
- graphics :: segments(top $ x , top $ y , right $ x , right $ y )
62
- graphics :: segments(top $ x , top $ y , left $ x , left $ y )
63
- graphics :: segments(left $ x , left $ y , right $ x , right $ y )
64
- }
65
-
66
- ternaryLabels <- function (top = " " , left = " " , right = " " ) {
67
- topCoord <- cartesianFromTernary(100 , 0 , 0 )
68
- leftCoord <- cartesianFromTernary(0 , 100 , 0 )
69
- rightCoord <- cartesianFromTernary(0 , 0 , 100 )
70
- graphics :: text(topCoord $ x , topCoord $ y , top , pos = 3 )
71
- graphics :: text(leftCoord $ x , leftCoord $ y , left , pos = 1 , srt = - 60 )
72
- graphics :: text(rightCoord $ x , rightCoord $ y , right , pos = 1 , srt = 60 )
73
- }
74
-
75
- ternaryGrid <- function (increment ) {
76
- low <- increment
77
- high <- 100 - increment
78
-
79
- m <- seq(low , high , increment )
80
- nLines <- length(m )
81
-
82
- n1 <- o2 <- seq(high , low , - increment )
83
- n2 <- o1 <- rep(0 , nLines )
84
-
85
- for (i in 1 : nLines ) {
86
- a <- cartesianFromTernary(m [i ], n1 [i ], o1 [i ])
87
- b <- cartesianFromTernary(m [i ], n2 [i ], o2 [i ])
88
- graphics :: segments(a $ x , a $ y , b $ x , b $ y , col = " lightgray" , lty = 3 )
89
-
90
- a <- cartesianFromTernary(n1 [i ], m [i ], o1 [i ])
91
- b <- cartesianFromTernary(n2 [i ], m [i ], o2 [i ])
92
- graphics :: segments(a $ x , a $ y , b $ x , b $ y , col = " lightgray" , lty = 3 )
93
-
94
- a <- cartesianFromTernary(n1 [i ], o1 [i ], m [i ])
95
- b <- cartesianFromTernary(n2 [i ], o2 [i ], m [i ])
96
- graphics :: segments(a $ x , a $ y , b $ x , b $ y , col = " lightgray" , lty = 3 )
97
- }
98
- }
99
-
100
- # # Convert from ternary coordinates to cartesian (x, y) coordinates ----------------------
101
- cartesianFromTernary <- function (top , left , right ) {
102
- y <- (top - 50 ) / 50 # vertically spans from -1 to 1
103
- baseHalfWidth <- 2 / tan(60 * pi / 180 ) # : equilateral triangle
104
- horizontalHalfWidth <- ((100 - top ) * baseHalfWidth ) / 100
105
- horizontalProportion <- (right / (right + left + 0.0000001 ) - 0.5 ) * 2
106
- x <- horizontalProportion * horizontalHalfWidth
107
- xyCoords <- data.frame (cbind(x = x , y = y ))
108
- colnames(xyCoords ) <- c(" x" , " y" )
109
- xyCoords
110
- }
111
-
112
- # # Remove rows with NA values and rows that don't sum to 100 -----------------------------
113
- validatedTernaryPoints <- function (x ) {
114
- rowsWithNA <- rowSums(is.na(x ))
115
- xNAremoved <- x [rowsWithNA == 0 , ]
116
- rowsEqualing100 <- abs(rowSums(xNAremoved ) - 100 ) < = 2
117
- xFinal <- xNAremoved [rowsEqualing100 , ]
118
- xFinal
119
- }
1
+ # # Create a ternary plot from a data frame
2
+ # ternaryPlot <- function(x, plotPoints = TRUE, labels = c("", "", ""), grid = TRUE, increment = 20, ...) {
3
+ # ternaryTriangle()
4
+ # ternaryLabels(labels[1], labels[2], labels[3])
5
+ # if (grid == TRUE) {
6
+ # ternaryGrid(increment)
7
+ # }
8
+ # if (plotPoints == TRUE) {
9
+ # ternaryPoints(x, ...)
10
+ # }
11
+ # }
12
+ #
13
+ # # Add points from a data frame to an existing ternary plot
14
+ # ternaryPoints <- function(x, ...) {
15
+ # x <- validatedTernaryPoints(x)
16
+ # coords <- cartesianFromTernary(x[, 1], x[, 2], x[, 3])
17
+ # graphics::points(coords$x, coords$y, ...)
18
+ # }
19
+ #
20
+ # # Add a line segment to an existing ternary plot
21
+ # # Color and line type may be added as additional arguments
22
+ # ternarySegment <- function(x0, x1, ...) {
23
+ # # x0 and x1 are vectors of the endpoint ternary coordinates
24
+ # coords0 <- cartesianFromTernary(x0[1], x0[2], x0[3])
25
+ # coords1 <- cartesianFromTernary(x1[1], x1[2], x1[3])
26
+ # graphics::segments(coords0$x, coords0$y, coords1$x, coords1$y, ...)
27
+ # }
28
+ #
29
+ # # Add a polygon to an existing ternary plot
30
+ # # Color may be added as an additional argument
31
+ # ternaryPolygon <- function(x, ...) {
32
+ # nPoints <- nrow(x)
33
+ # xCoord <- vector(mode = "numeric", length = nPoints)
34
+ # yCoord <- vector(mode = "numeric", length = nPoints)
35
+ # for (i in 1:nPoints) {
36
+ # coords <- cartesianFromTernary(x[i, 1], x[i, 2], x[i, 3])
37
+ # xCoord[i] <- coords$x
38
+ # yCoord[i] <- coords$y
39
+ # }
40
+ # graphics::polygon(xCoord, yCoord, ...)
41
+ # }
42
+ #
43
+ # # Add text to an existing ternary plot
44
+ # # Text styling may be added as additional arguments
45
+ # ternaryText <- function(x, label = "", ...) {
46
+ # coords <- cartesianFromTernary(x[1], x[2], x[3])
47
+ # graphics::text(coords$x, coords$y, label = label, ...)
48
+ # }
49
+ #
50
+ # # ---------------------------------------------------------------------------------------
51
+ # # The following functions are called by ternaryPlot() and generally will not need to be
52
+ # # called directly
53
+ #
54
+ # # # Plotting primitives -------------------------------------------------------------------
55
+ # ternaryTriangle <- function() {
56
+ # top <- cartesianFromTernary(100, 0, 0)
57
+ # left <- cartesianFromTernary(0, 100, 0)
58
+ # right <- cartesianFromTernary(0, 0, 100)
59
+ # lim <- c(-1.1, 1.1)
60
+ # graphics::plot(top$x, top$y, xlim = lim, ylim = lim, type = "n", asp = 1, axes = FALSE, xlab = "", ylab = "")
61
+ # graphics::segments(top$x, top$y, right$x, right$y)
62
+ # graphics::segments(top$x, top$y, left$x, left$y)
63
+ # graphics::segments(left$x, left$y, right$x, right$y)
64
+ # }
65
+ #
66
+ # ternaryLabels <- function(top = "", left = "", right = "") {
67
+ # topCoord <- cartesianFromTernary(100, 0, 0)
68
+ # leftCoord <- cartesianFromTernary(0, 100, 0)
69
+ # rightCoord <- cartesianFromTernary(0, 0, 100)
70
+ # graphics::text(topCoord$x, topCoord$y, top, pos = 3)
71
+ # graphics::text(leftCoord$x, leftCoord$y, left, pos = 1, srt = -60)
72
+ # graphics::text(rightCoord$x, rightCoord$y, right, pos = 1, srt = 60)
73
+ # }
74
+ #
75
+ # ternaryGrid <- function(increment) {
76
+ # low <- increment
77
+ # high <- 100 - increment
78
+ #
79
+ # m <- seq(low, high, increment)
80
+ # nLines <- length(m)
81
+ #
82
+ # n1 <- o2 <- seq(high, low, -increment)
83
+ # n2 <- o1 <- rep(0, nLines)
84
+ #
85
+ # for (i in 1:nLines) {
86
+ # a <- cartesianFromTernary(m[i], n1[i], o1[i])
87
+ # b <- cartesianFromTernary(m[i], n2[i], o2[i])
88
+ # graphics::segments(a$x, a$y, b$x, b$y, col = "lightgray", lty = 3)
89
+ #
90
+ # a <- cartesianFromTernary(n1[i], m[i], o1[i])
91
+ # b <- cartesianFromTernary(n2[i], m[i], o2[i])
92
+ # graphics::segments(a$x, a$y, b$x, b$y, col = "lightgray", lty = 3)
93
+ #
94
+ # a <- cartesianFromTernary(n1[i], o1[i], m[i])
95
+ # b <- cartesianFromTernary(n2[i], o2[i], m[i])
96
+ # graphics::segments(a$x, a$y, b$x, b$y, col = "lightgray", lty = 3)
97
+ # }
98
+ # }
99
+ #
100
+ # # # Convert from ternary coordinates to cartesian (x, y) coordinates ----------------------
101
+ # cartesianFromTernary <- function(top, left, right) {
102
+ # y <- (top - 50) / 50 # vertically spans from -1 to 1
103
+ # baseHalfWidth <- 2 / tan(60 * pi / 180) # : equilateral triangle
104
+ # horizontalHalfWidth <- ((100 - top) * baseHalfWidth) / 100
105
+ # horizontalProportion <- (right / (right + left + 0.0000001) - 0.5) * 2
106
+ # x <- horizontalProportion * horizontalHalfWidth
107
+ # xyCoords <- data.frame(cbind(x = x, y = y))
108
+ # colnames(xyCoords) <- c("x", "y")
109
+ # xyCoords
110
+ # }
111
+ #
112
+ # # # Remove rows with NA values and rows that don't sum to 100 -----------------------------
113
+ # validatedTernaryPoints <- function(x) {
114
+ # rowsWithNA <- rowSums(is.na(x))
115
+ # xNAremoved <- x[rowsWithNA == 0, ]
116
+ # rowsEqualing100 <- abs(rowSums(xNAremoved) - 100) <= 2
117
+ # xFinal <- xNAremoved[rowsEqualing100, ]
118
+ # xFinal
119
+ # }
120
120
121
121
# Fabric intensities and plots -------------------------------------------------
122
122
@@ -127,15 +127,17 @@ validatedTernaryPoints <- function(x) {
127
127
# '
128
128
# ' @returns numeric vector containing the fabric shape and intensity indices:
129
129
# ' \describe{
130
- # ' \item{`P`}{Point (Vollmer 1990), range : (0, 1)}
131
- # ' \item{`G`}{Girdle (Vollmer 1990), range : (0, 1)}
132
- # ' \item{`R`}{Random (Vollmer 1990), range : (0, 1)}
133
- # ' \item{`B`}{cylindricity (Vollmer 1990), range : (0, 1)}
134
- # ' \item{`C`}{cylindricity or Fabric strength (Woodcock 1977), range : (0, Inf)}
135
- # ' \item{`I`}{cylindricity or Fabric intensity (Lisle 1985), range : (0, 5)}
136
- # ' \item{`D`}{"distance" from uniformity, linear from R to P, and R to G. End members are: uniform D = 0, girdle D = 0.5, cluster D = 1. The 99% level for a test against uniformity for a sample size of 300 is D = 0.1 (Vollmer 2020) .}
130
+ # ' \item{`P`}{Point (Vollmer 1990). Range : (0, 1)}
131
+ # ' \item{`G`}{Girdle (Vollmer 1990). Range : (0, 1)}
132
+ # ' \item{`R`}{Random (Vollmer 1990). Range : (0, 1)}
133
+ # ' \item{`B`}{cylindricity (Vollmer 1990). Range : (0, 1)}
134
+ # ' \item{`C`}{cylindricity or Fabric strength (Woodcock 1977). Rrange : (0, Inf)}
135
+ # ' \item{`I`}{cylindricity or Fabric intensity (Lisle 1985). Range : (0, 5)}
136
+ # ' \item{`D`}{"distance" from uniformity, linear from R to P, and R to G (Vollmer 2020). Range: (0, 1). End members are: uniform D = 0, girdle D = 0.5, cluster D = 1. The 99% level for a test against uniformity for a sample size of 300 is D = 0.1.}
137
137
# ' }
138
138
# ' @export
139
+ # '
140
+ # ' @seealso [or_shape_params()]
139
141
# '
140
142
# ' @examples
141
143
# ' set.seed(1)
0 commit comments