@@ -6,124 +6,71 @@ draw.curves<-function(x){
66 if (segment.test ){
77 segment.list <- append(
88 list (x0 = x $ x [1 : 100 ], x1 = x $ x [2 : 101 ], y0 = x $ y [1 : 100 ], y1 = x $ y [2 : 101 ]),
9- x [- c(1 : 2 , 5 )])
9+ x [- c(1 : 2 )])
10+ segment.list <- segment.list [- which(names(segment.list )== " arrows" )]
1011 do.call(" segments" , segment.list )
11- }else {do.call(" lines" , x [1 : 4 ])}
12+ }else {
13+ if (any(names(x )== " arrows" )){x <- x [- which(names(x )== " arrows" )]}
14+ do.call(" lines" , x )}
1215 }
1316
1417
1518# generate a list in which each entry is a list of line attributes, to pass to draw.curves()
1619get.curves <- function (
17- input
20+ points , # from calc.circleplot
21+ lines ,
22+ plot.options # from set.plot.attributes
1823 )
1924 {
2025
2126 # calculate inter-point distances, to allow setting of pc.scale (to calculate curvature of lines relative to origin)
22- point.distance <- dist(input $ points [, 2 : 3 ])
27+ point.distance <- dist(points [, c( " x " , " y " ) ])
2328 scale.distance <- point.distance - min(point.distance )
2429 scale.distance <- ((scale.distance / max(scale.distance ))*
25- input $ plot.control $ line.curvature [2 ])+ input $ plot.control $ line.curvature [1 ]
30+ plot.options $ line.curvature [2 ])+ plot.options $ line.curvature [1 ]
2631 scale.distance <- as.matrix(scale.distance )
2732
28- # set line colours & widths.
29- # Note that this works even for binary matrices, but is later ignored if line.gradient==FALSE
30- line.cuts <- cut(input $ lines $ value , input $ plot.control $ line.breaks ,
31- include.lowest = TRUE , right = TRUE , labels = FALSE )
32- input $ lines $ colour <- input $ plot.control $ line.cols [line.cuts ]
33-
34- # new code for setting line widths
35- input $ lines $ lwd.max <- input $ plot.control $ line.widths [line.cuts ]
36- input $ lines $ lwd.min <- input $ plot.control $ line.widths [line.cuts ]* input $ plot.control $ line.expansion
37-
38- # add line to remove NA values if plot.control$na.control is not a list
39- # this reduces the time taken to draw plots with many NA values
40- if (class(input $ plot.control $ na.control )!= " list" ){
41- if (any(is.na(input $ lines $ value ))){
42- input $ lines <- input $ lines [- which(is.na(input $ lines $ value )== TRUE ), ]}}
43-
4433 # loop to calculate lines of requisite location and colour
45- # line.list<-apply(input$lines, 1, FUN=function(x, input, distance){calc.lines(x, input, distance)},
46- # input=input, distance=scale.distance)
47- # for some reason, apply() fails here, while a loop works; implement a loop until this is resolved.
48- line.list <- list ()
49- for (i in 1 : nrow(input $ lines )){line.list [[i ]]<- calc.lines(input $ lines [i , ], input , distance = scale.distance )}
50-
34+ line.list <- split(lines , c(1 : nrow(lines )))
35+ line.list <- lapply(line.list , function (x , input , distance , plot.options ){
36+ calc.lines(x , input , distance , plot.options )},
37+ input = points , distance = scale.distance , plot.options = plot.options )
38+ names(line.list )<- apply(lines [, 1 : 2 ], 1 , function (x ){paste(x , collapse = " _" )})
5139 return (line.list )
5240 }
5341
5442
5543# function to pass to apply in get.curves() to calculate locations for each line
56- calc.lines <- function (lines , input , distance )
44+ calc.lines <- function (x , points , distance , plot.options )
5745 {
58- # sort out line inputs
59- sp1 <- as.character(lines [1 ])
60- sp2 <- as.character(lines [2 ])
61- value <- as.numeric(lines [3 ])
62- col <- as.character(lines [5 ])
63- lwd.min <- as.numeric(lines [7 ])
64- lwd.max <- as.numeric(lines [6 ])
65-
66- # sort out other inputs
67- points <- input $ points
68- plot.control <- input $ plot.control
69- binary <- input $ binary
70- asymmetric <- input $ asymmetric
71-
7246 # sort out coords for this row
73- row1 <- which(points $ label == sp1 )
74- row2 <- which(points $ label == sp2 )
47+ row1 <- which(points $ labels == x $ sp1 )
48+ row2 <- which(points $ labels == x $ sp2 )
7549 coords <- data.frame (x = points $ x [c(row1 , row2 )], y = points $ y [c(row1 , row2 )])
76-
50+
7751 # find basic spatial info on these points
7852 distance.thisrun <- distance [row1 , row2 ]
7953 coords.scaled <- triangle.coords(coords , distance.thisrun ) # what coordinates should the curve be fit to?
8054
8155 # calculate the curve that fits between these points.
82- # Note that if there are an even number of points, some will pass through the intercept, causing earlier code to fail
8356 if (coords.scaled $ y [2 ]> 0.0001 ){
8457 apex <- curve.apex(coords , distance.thisrun )
8558 curve.coords <- fit.quadratic(coords.scaled )
86- new.curve <- as.list( reposition.curve(curve.coords , apex ) )
59+ new.curve <- reposition.curve(curve.coords , apex , coords )
8760 }else { # i.e. if a straight line
8861 new.curve <- list (
8962 x = seq(coords $ x [1 ], coords $ x [2 ], length.out = 101 ),
90- y = seq(coords $ y [1 ], coords $ y [2 ], length.out = 101 ))
63+ y = seq(coords $ y [1 ], coords $ y [2 ], length.out = 101 ))
9164 }
9265
93- # set NA behaviour
94- if (is.na(value )){
95- if (is.list(plot.control $ na.control )){
96- new.curve <- append(new.curve , plot.control $ na.control )
97- new.curve <- append(new.curve , list (direction = as.numeric(lines [4 ])))
98- }
99- }else { # i.e. if this line is not a missing value (i.e. most cases).
100-
101- # set line widths
102- lwd.range <- lwd.max - lwd.min
103- if (lwd.range > 0 ){
104- # set default line widths (0-1 range) assuming expansion >0
105- x <- seq(- 2 , 2 , length.out = 100 )
106- line.widths <- dnorm(x , mean = 0 , sd = 0.5 )
107- line.widths <- line.widths - min(line.widths )
108- line.widths <- line.widths / max(line.widths )
109- lwd.final <- (line.widths * lwd.range )+ lwd.min
110- }else {lwd.final <- lwd.max }
111-
11266 # ensure that curves run from their start to end point
113- large.x <- which(sqrt(coords $ x ^ 2 )> 10 ^- 3 )
114- if (length(large.x )> 1 ){large.x <- 1 }
115- if (large.x == 1 ){order.test <- new.curve $ x [1 ]- coords $ x [large.x ]
116- }else {order.test <- new.curve $ x [101 ]- coords $ x [large.x ]}
117- if (sqrt(order.test ^ 2 )> 10 ^- 4 ){
118- new.curve $ x <- new.curve $ x [101 : 1 ]
119- new.curve $ y <- new.curve $ y [101 : 1 ]}
120- # if direction states that the line be reversed, do so.
121- if (as.numeric(lines [4 ])== 2 ){
67+ first.x <- which.min(sqrt((coords $ x [1 ]- new.curve $ x )^ 2 ))
68+ if (first.x > 1 ){
12269 new.curve $ x <- new.curve $ x [101 : 1 ]
12370 new.curve $ y <- new.curve $ y [101 : 1 ]}
12471
12572 # set line colours
126- if (binary & plot.control $ line.gradient ){ # for the special case where line colours are set by point colours
73+ if (plot.options $ line.gradient ){ # for the special case where line colours are set by point colours
12774 # get line colours from input$points
12875 color1 <- points $ col [row1 ]
12976 color2 <- points $ col [row2 ]
@@ -133,15 +80,11 @@ calc.lines<-function(lines, input, distance)
13380 # ensure colours are in correct order
13481 distance.pos <- sqrt((new.curve $ x [1 ]- points $ x [row1 ])^ 2 )
13582 if (distance.pos > 0.001 ){colours.final <- colours.final [100 : 1 ]}
136- }else {colours.final <- col } # in all other cases
83+ }else {colours.final <- x $ col } # in all other cases
13784
13885 # export
139- new.curve <- append(new.curve , list (
140- col = as.character(colours.final ),
141- lwd = as.numeric(lwd.final ),
142- direction = as.numeric(lines [4 ])))
143-
144- } # end if(is.na())==F
86+ new.curve <- append(new.curve , x [- c(1 : 3 )])
87+ if (plot.options $ line.gradient ){new.curve $ col <- colours.final }
14588
14689 return (new.curve )
14790
@@ -150,13 +93,8 @@ calc.lines<-function(lines, input, distance)
15093
15194
15295# function to determine what kind of arrowhead to draw (if any) and then draw result from get.arrows()
153- # note: if(asymmetric) is already called; so we only need to know whether an arrow should be drawn, and in which direction
15496draw.arrows <- function (x , attr ){
155- invisible (switch (x $ direction ,
156- 1 == {draw <- TRUE ; reverse <- FALSE },
157- 2 == {draw <- TRUE ; reverse <- TRUE },
158- 3 == {draw <- FALSE ; reverse <- NA }))
159- if (draw ){
97+ if (x $ arrows ){
16098 if (length(x $ col )> 1 ){col.final <- x $ col [ceiling(101 * attr $ distance )]
16199 }else {col.final <- x $ col }
162100 polygon(get.arrows(x , attr , reverse ), border = NA , col = col.final )}
0 commit comments