Skip to content

Commit b2e66cd

Browse files
committed
Merge branch 'faster-ordipointlabel'
2 parents fb5370a + 675a213 commit b2e66cd

File tree

3 files changed

+154
-139
lines changed

3 files changed

+154
-139
lines changed

R/ordipointlabel.R

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,8 @@
6666
## and we loop
6767
box <- matrix(0, nrow(xy), 2)
6868
for (i in seq_len(nrow(xy))) {
69-
box[i,1] <- strwidth(labels[i], cex = cex[i], font = font[i]) +
70-
strwidth("m", cex = cex[i], font = font[i])
71-
box[i,2] <- strheight(labels[i], cex = cex[i], font = font[i]) +
72-
strheight("x", cex = cex[i], font = font[i])
69+
box[i,1] <- strwidth(labels[i], cex = cex[i], font = font[i]) + em/1.5
70+
box[i,2] <- strheight(labels[i], cex = cex[i], font = font[i]) + ex/1.5
7371
}
7472
## offset: 1 up, 2..4 sides, 5..8 corners
7573
makeoff <- function(pos, lab) {
@@ -78,23 +76,32 @@
7876
}
7977
## amount of overlap
8078
overlap <- function(xy1, off1, xy2, off2) {
81-
pmax(0, pmin(xy1[,1] + off1[,1]/2, xy2[,1] + off2[,1]/2)
82-
-pmax(xy1[,1] - off1[,1]/2, xy2[,1] - off2[,1]/2)) *
83-
pmax(0, pmin(xy1[,2] + off1[,2]/2, xy2[,2] + off2[,2]/2)
84-
-pmax(xy1[,2] - off1[,2]/2, xy2[,2] - off2[,2]/2))
79+
pmax.int(0, pmin.int(xy1[,1] + off1[,1]/2, xy2[,1] + off2[,1]/2)
80+
-pmax.int(xy1[,1] - off1[,1]/2, xy2[,1] - off2[,1]/2)) *
81+
pmax.int(0, pmin.int(xy1[,2] + off1[,2]/2, xy2[,2] + off2[,2]/2)
82+
-pmax.int(xy1[,2] - off1[,2]/2, xy2[,2] - off2[,2]/2))
8583
}
8684
## indices of overlaps in lower triangular matrix
8785
n <- nrow(xy)
8886
j <- as.vector(as.dist(row(matrix(0, n, n))))
8987
k <- as.vector(as.dist(col(matrix(0, n, n))))
9088
## Find labels that may overlap...
91-
maylap <- overlap(xy[j,], 2*box[j,], xy[k,], 2*box[k,]) > 0
89+
maylap <- overlap(xy[j,], 2*box[j,] - c(em,ex)/1.5,
90+
xy[k,], 2*box[k,] - c(em,ex)/1.5) > 0
9291
## ... and work only with those
9392
j <- j[maylap]
9493
k <- k[maylap]
9594
jk <- sort(unique(c(j,k)))
96-
## SANN: no. of iterations & starting positions
97-
nit <- min(64 * length(jk), 10000)
95+
## SANN: starting values & starting positions. nit is the number
96+
## of iterations, temp is the starting temperature, tmax the
97+
## number of evaluations at the same temperature. Hotter
98+
## temperatures allow worse moves in the beginning. The "idea"
99+
## behind 0.791: if you try n positions for n points, you try
100+
## 0.632*n labels, and if you try 0.791*n, you try half of labels
101+
## (some repeatedly).
102+
nit <- min(64 * length(jk), 10000) # default 10000
103+
temp <- 5 # default 10
104+
tmax <- ceiling(0.791 * length(jk)) # default 10
98105
pos <- ifelse(xy[,2] > 0, 1, 3)
99106
## Criterion: overlap + penalty for moving towards origin and also
100107
## for corners. Penalty is mild: max 1 ltr and one-character
@@ -118,15 +125,15 @@
118125
}
119126
## Simulated annealing
120127
sol <- optim(par = pos, fn = fn, gr = gr, method="SANN",
121-
control=list(maxit=nit))
128+
control=list(maxit=nit, tmax=tmax, temp=temp))
122129
lab <- xy + makeoff(sol$par, box)
123130
dev.hold()
124131
on.exit(dev.flush())
125132
## draw optional lab background first so it does not cover points
126133
if (!missing(bg)) {
127134
for(i in seq_len(nrow(lab))) {
128-
polygon(lab[i,1] + c(-1,1,1,-1)*box[i,1]/2.2,
129-
lab[i,2] + c(-1,-1,1,1)*box[i,2]/2.2,
135+
polygon(lab[i,1] + c(-1,1,1,-1)*box[i,1]/2,
136+
lab[i,2] + c(-1,-1,1,1)*box[i,2]/2,
130137
col = fill[i], border = col[i], xpd = TRUE)
131138
ordiArgAbsorber(lab[i,1], lab[i,2], labels = labels[i],
132139
col = col[i], cex = cex[i], font = font[i],

man/ordipointlabel.Rd

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@
55

66
\title{ Ordination Plots with Points and Optimized Locations for Text }
77

8-
\description{ Function produces ordination plots with points and text
9-
labels to the points. The points are in the fixed locations given by
10-
the ordination, but the locations of the text labels are optimized to
11-
minimize overplotting. The function is useful with moderately crowded
12-
ordination plots.
13-
}
8+
\description{ Function produces ordination plots with labelled
9+
points. The points are in the fixed locations given by the
10+
ordination, but the locations of the text labels are optimized to
11+
minimize overplotting. The function is useful with moderately
12+
crowded ordination plots. }
1413

1514
\usage{
1615
ordipointlabel(x, display = c("sites", "species"), choices = c(1, 2),
@@ -75,6 +74,7 @@ ordipointlabel(x, display = c("sites", "species"), choices = c(1, 2),
7574
examples.
7675

7776
}
77+
7878
\value{
7979
The function returns invisibly an object of class
8080
\code{ordipointlabel} with items \code{xy} for coordinates of

0 commit comments

Comments
 (0)