The R Project SVN R

Rev

Rev 88200 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
80947 maechler 1
#### Regression tests for GRAPHICS & PLOTS -- requiring strict PDF equality
23048 ripley 2
 
77881 murrell 3
pdf("reg-plot.pdf", paper="a4r", encoding ="ISOLatin1.enc", compress = FALSE,
4
    useDingbats = TRUE)
57488 ripley 5
 
23048 ripley 6
## since we supply the font metrics, the results depend only on
56953 ripley 7
## the encoding used: Windows is different from Unix by default.
23048 ripley 8
 
57488 ripley 9
options(warn = 1) # print as they occur
23048 ripley 10
 
11
plot(0) # this should remain constant
12
str(par(c("usr","xaxp","yaxp")))
71645 maechler 13
stopifnot(all.equal(
14
    par(c("usr","xaxp","yaxp"))
15
   ,
16
    list(usr = c(0.568, 1.432, -1.08, 1.08),
17
         xaxp = c(0.6, 1.4, 4), yaxp = c(-1, 1, 4))))
23048 ripley 18
 
19
 
20
### Test for centring of chars.  All the chars which are plotted should
21
### be centred, and there should be no warnings about
22
### font metrics unknown for character `?'
23
 
24
par(pty="s")
25
plot(c(-1,16), c(-1,16), type="n", xlab="", ylab="", xaxs="i", yaxs="i")
26
title("Centred chars in default char set (ISO Latin1)")
27
grid(17, 17, lty=1)
32436 ripley 28
known <- c(32:126, 160:255)
23048 ripley 29
 
30
for(i in known) {
31
    x <- i %% 16
32
    y <- i %/% 16
44151 ripley 33
    points(x, y, pch=-i)
23048 ripley 34
}
35
 
36
par(pty="m")
37
 
38
## PR 816 (label sizes in dotchart)
39
 
40
### Prior to 1.2.2, the label sizes were unaffected by cex.
41
 
42
dotchart(VADeaths, main = "Death Rates in Virginia - 1940", cex = 0.5)
43
dotchart(VADeaths, main = "Death Rates in Virginia - 1940", cex = 1.5)
44
 
45
## killed by 0 prior to 1.4.0 and in 1.4.1:
46
t1 <- ts(0:100)
47
## only warnings about values <= 0
48
plot(t1, log = "y")
49
plot(cbind(t1, 10*t1, t1 - 4), log="y", plot.type = "single")
50
stopifnot(par("usr")[4] > 3) # log10: ylim[2] = 1000
51
 
52
 
53
## This one needs to be looked at.
54
## lty = "blank" killed the fill colour too.
55
plot(1:10, type="n")
56
polygon(c(1, 3, 3, 1), c(1, 1, 3, 3), col="yellow", border="red", lty="blank")
57
rect(6, 6, 10, 10,  col="blue", border="red", lty="blank")
58
## in 1.5.0 all omit the fill colours.
59
with(trees, symbols(Height, Volume, circles=Girth/24, inches=FALSE,
60
                    lty="blank", bg="blue"))
61
## in 1.5.0 ignored the lty.
62
 
86239 ripley 63
## axis() and par(mgp < 0)
64
lt <-"31" # in R
23048 ripley 65
x <- seq(-2,3, len=1001)
66
op <- par(tck= +0.02, mgp = -c(3,2,0))
67
plot(x, x^2 - 1.2, xaxt = "n", xlab="", type ='l', col = 2,
68
     main = "mgp < 0: all ticks and labels inside `frame'")
69
x <- -2:3
70
lines(x, x^2 - 1.2, type ="h", col = 3, lwd=3)
71
axis(1, pos = 0, at=-1:1, lty = lt, col=4)## col & lty work only from R 1.6
72
par(op)
73
axis(1, pos = 0, at=c(-2,2,3), lty = lt, col=4)
74
mtext(side=1,"note the x-ticks on the other side of the bars")
75
 
23846 maechler 76
## plot.table(): explicit xlab and ylab for non-1D
23048 ripley 77
plot(UCBAdmissions)# default x- and y-lab
78
plot(UCBAdmissions, xlab = "x label", ylab = "YY")# wrong in 1.5.1
23846 maechler 79
##   axis suppression
80
plot(tt <- table(c(rep(0,7), rep(1,4), rep(5, 3))), axes = FALSE)
81
plot(tt, xaxt = "n")
82
## wrong till (incl.) 1.6.x
25869 maechler 83
 
84
## legend with call
85
lo <- legend(2,2, substitute(hat(theta) == that, list(that= pi)))
86
stopifnot(length(lo$text$x) == 1)
87
## length() was 3 till 1.7.x
26717 maechler 88
 
89
plot(ecdf(c(1:4,8,12)), ylab = "ECDF", main=NULL)
90
## ylab didn't work till 1.8.0
29381 maechler 91
 
92
plot(1:10, pch = NA) # gave error till 1.9.0
93
points(1:3, pch=c("o",NA,"x"))# used "N"
94
try(points(4, pch=c(NA,FALSE)))# still give an error
30819 maechler 95
 
96
## 'lwd' should transfer to plot symbols
97
legend(1,10, c("A","bcd"), lwd = 2:3, pch= 21:22, pt.bg="skyblue",
98
       col = 2:3, bg = "thistle")
99
## (gave an error for 2 days in "2.0.0 unstable")
33335 maechler 100
 
101
x <- 2^seq(1,1001, length=20)
102
plot(x, x^0.9, type="l", log="xy")
103
## gave error 'Infinite axis extents [GEPretty(1.87013e-12,inf,5)]' for R 2.0.1
35127 maechler 104
 
105
plot(as.Date("2001/1/1") + 12*(1:9), 1:9)
106
## used bad 'xlab/ylab' in some versions of R 2.2.0(unstable)
39725 maechler 107
 
40032 maechler 108
## dotchart() restoring par()
39725 maechler 109
Opar <- par(no.readonly=TRUE) ; dotchart(1:4, cex= 0.7)
110
Npar <- par(no.readonly=TRUE)
40032 maechler 111
ii <- c(37, 50:51, 58:59, 63)
112
stopifnot(identical(names(Opar)[ii],
113
                    c("mai","pin","plt","usr","xaxp","yaxp")),
114
          identical(Opar[-ii], Npar[-ii]))
115
## did not correctly restore par("mar") up to (incl) R 2.4.0
116
 
43202 maechler 117
## plot.function()     [n=11, ... : since we store and diff PS file !]
118
plot(cos,       xlim=c(-5,5), n=11, axes=FALSE); abline(v=0)
43181 maechler 119
## did *not* plot for negative x up to R 2.5.1
43202 maechler 120
plot(sin, -2,3, xlim=c(-5,5), n=11, axes=FALSE, xlab="")# plot from -2
121
axis(1, at=c(-2,3), tcl=-1); axis(1, at=c(-5,5))
122
## (from,to) & xlim  should work simultaneously
123
 
43181 maechler 124
plot(cos, -7,7, n=11, axes=FALSE)
125
## gave wrong ylab in R 2.6.0
126
plot(cos, -7,7, ylab = "Cosine  cos(x)", n=11, axes=FALSE)
127
## partial matching of 'ylab'; mapping  [0,1] (not [-7.7]):
88200 smeyer 128
## margins chosen to avoid rounding error showing to 2dp.
43286 ripley 129
op <- par(mar=c(5,4.123,4,2)+0.1)
43181 maechler 130
plot(gamma, yla = expression(Gamma(x)), n=11, yaxt="n")
43286 ripley 131
par(op)
43202 maechler 132
 
43526 maechler 133
## plot.ts(x, y) could get the labels wrong in R <= 2.6.0:
134
x <- ts(1:5);x1 <- lag(x, 2); plot(x1, x, axes=FALSE)
43636 maechler 135
 
136
# adding a curve in log scale :
137
curve(5*exp(-x), 0.1, 100, n = 3, log="x", ylab="", axes=FALSE)
138
curve(5*exp(-x), add=TRUE, n = 3, col=2,lwd=3)
139
## should fully overplot; wrong default xlim in 2.6.1
140
## (and *slightly* wrong up to 2.6.0)
45449 maechler 141
 
142
## Axis() calls via plot()  {[xy]axt to keep *.ps small}
143
x <- as.Date("2008-04-22 09:45") + (i <- c(0,4))
144
plot(x,    xaxt="n")# not ok in 2.6.2, nor 2.7.0
145
plot(x, i, yaxt="n")# ok in 2.6.2  and 2.7.0
146
plot(i, x, xaxt="n")# ok in 2.6.2 and not in 2.7.0
54481 ripley 147
 
148
## table methods should be bypassed:
149
dotchart(table(infert$education))
150
## failed in 2.12.[12]
62846 maechler 151
 
152
## cex as "..."  in "high level" function
153
hc <- hclust(dst <- dist(c(1:2, 5)), method="ave")
154
plot(hc, cex = 2, axes=FALSE, ann=FALSE)
155
## cex was not used in 3.0.[01]
156
 
71118 maechler 157
## axis.Date() and axis.POSIXct() with reversed 'xlim'
71128 maechler 158
toD <- as.Date("2016-08-19"); dates <- c(toD - 10, toD)
71118 maechler 159
plot(dates, 1:2, xlim = rev(dates),
160
     ann=FALSE, yaxt="n", frame.plot=FALSE)
161
## failed to label the dates in R <= 3.3.1
74863 maechler 162
 
83601 ligges 163
## axis.Date() with various data types:
164
x <- seq(as.Date("2022-01-20"), as.Date("2023-03-21"), by = "days")
165
plot(data.frame(x, y = 1), xaxt = "n")
166
axis.Date(1)
167
axis.Date(3, at = "2022-04-01")
168
axis.Date(3, at = as.Date("2022-07-01"))
169
axis.Date(3, at = as.POSIXct(as.Date("2022-10-01")))
170
axis.Date(3, at = as.POSIXlt(as.Date("2023-01-01")))
171
axis.Date(3, at = as.integer(as.Date("2023-04-01")))
172
## automatically extends the format:
173
axis.Date(1, at = "2022-02-15", tck = -0.05, mgp = c(3,2,0))
74863 maechler 174
 
83601 ligges 175
## axis.POSIXct() with various data types (2 minutes)
176
x <- as.POSIXct("2022-10-01") + c(0, 60, 120)
177
plot(data.frame(x, y = 1), xaxt="n")
178
axis.POSIXct(1)
179
axis.POSIXct(3, at = "2022-10-01 00:01")
180
axis.POSIXct(3, at = as.Date("2022-10-01"))
181
axis.POSIXct(3, at = as.POSIXct("2022-10-01 00:01:30"))
182
axis.POSIXct(3, at = as.POSIXlt("2022-10-01 00:02"))
183
axis.POSIXct(3, at = as.numeric(as.POSIXct("2022-10-01 00:00:30")))
184
## automatically extends format (here: subseconds):
185
axis.POSIXct(3, at = "2022-10-01 00:00:30.25", mgp = c(3,2,0))
186
 
187
## axis.POSIXct: a few days, extending the format
188
days <- seq(as.Date("2022-10-01"), as.Date("2022-12-21"), by="days")
189
x <- as.POSIXct(as.character(days))
89700 smeyer 190
plot(data.frame(x = range(x), y = 1), xaxt="n")
83601 ligges 191
axis.POSIXct(1, x)
192
axis.POSIXct(1, x, at = as.Date("2022-10-12"), mgp = c(3,2,0), tck = -0.04)
193
axis.POSIXct(3, x, at = as.POSIXct("2022-10-15"))
194
axis.POSIXct(3, x, at = as.POSIXlt("2022-10-15"), mgp = c(3,2,0))
195
axis.POSIXct(1, x, at = "2022-11-01 23:00", mgp = c(3,2,0), tck = -0.04)
196
axis.POSIXct(3, x, at = "2022-11-01 06:00")
197
axis.POSIXct(3, x, at = as.numeric(as.POSIXct("2022-12-01")))
198
 
74863 maechler 199
## axis() -- labels only written when there's room
200
plot2 <- function(at, wait=FALSE) {
201
    plot1 <- function(x,y) plot(x,y, type="n", xlab="", ylab="", tck=0, frame.plot=FALSE)
202
    plot1( at, at); axis(3, at= at, tck=0)
203
    plot1(-at,-at); axis(3, at=-at, tck=0)
204
    if(wait) { mtext("Click here to advance!", line=-2, cex=1.5, col=2); locator(1) }
205
}
206
at <- c(7:15, 2*(8:15), 5*(7:15), 10*(8:15))
207
op <- par(mfrow=2:1, mgp = c(1.5, 0.6, 0), mar = .1+c(2,2,2,1),
208
          lab = c(20,20,7), las = 1) # las=1: all horizontal => y-axis perpendicular
209
interAct <- dev.interactive()
210
 
211
if(interAct) { xMar <- c(1,3)/2  ; nP <- 10
212
} else {       xMar <- c(1,3)*3/2; nP <-  3 }
213
## Now increasing margins ==> decreasing plot area ==> shrinking plot
214
## (*is* device dependent [here have "a4r"-pdf]) :
215
for(n in 1:nP) {
216
    par(mar = par("mar") + xMar)
217
    plot2(at, n < nP && interAct)
218
}
74871 maechler 219
par(op)
220
 
221
 
222
##----- pairs() using verInd & horInd ----------
223
mpairs <- function(..., p=3, npp=2, main) { # p=4, npp=7 was Chris Andrews' example
224
    x <- matrix((1:(p*npp))/npp, ncol=p, dimnames=list(NULL, paste0("x", 1:p)))
225
    ## -> x \in [1/npp,.., p]  <==> ceiling(x) \in {1,2,...,p}
226
    ## the panel function
227
    mP <- function(x,y, ...) { ## really made for the 'x = ...' above
228
        j <- ceiling(mean(y)) # in 1:p
229
        points(x,y, col=ceiling(mean(x)), pch= 3*j, cex=((p-1.5)*j+1)/p, ...)
230
        g <- 1:(p-1); abline(h=g, v=g, lty=3, col="gray33")
231
    }
232
    if(missing(main))
233
        main <- if(...length()) sub("mpairs", '', deparse(sys.call()))
234
    lim <- range(x)
235
    k <- max(2, npp-2) ## bug in R(?): par(lab = c(1,1,7)) giving nonsense!
236
    op <- par(lab = c(k,k,7), oma=c(1,0,0,0)); on.exit(par(op))
237
    pairs(x, panel=mP, xlim=lim, ylim=lim, main=main, cex.main=1, ...)
238
}
239
 
240
mpairs() # 4x4 matrix of scatterplots
241
if(interAct) dev.set(if(length(dev.list()) < 2) dev.new() else dev.prev())
242
mpairs(horInd=1:2,verInd=  1:3 ) # 3x2 matrix: upper left [WRONG in R <= 3.5.0]
243
mpairs(horInd=3:2)               # 2x4: middle rows swapped
244
mpairs(           verInd=c(3,1)) # 4x2: cols 3,1
245
##
246
## now all with  'row1attop=FALSE'=======
247
if(interAct) dev.set(dev.prev())
248
mpairs(row1attop=FALSE) # 4x4 matrix of scatterplots -- perfect in R <= 3.5.0
249
if(interAct) dev.set(dev.next())
250
## a version of those above, with 'row1attop = FALSE'
251
mpairs(horInd=2:1,verInd=3:1   , row1attop=FALSE) # 3x2: *swapped* upper left
252
mpairs(horInd=c(3,1)           , row1attop=FALSE) # 2x3: swapped outer rows
253
mpairs(           verInd=c(3,2), row1attop=FALSE) # 3x2: cols 3,2
75182 maechler 254
 
255
 
256
## axis() when in subnormal range (x is subnormal if 0 < x < .Machine$double.xmin):
257
(.min.exp.subnormal <- with(.Machine, double.min.exp + double.ulp.digits)) # -1074
258
(ry <- range(y74 <- 2^(.min.exp.subnormal + 0:50))) # all subnormal
259
plotNchk <- function(y) {
75196 maechler 260
    plot(y, log = "y", xlab="", ylab="", xaxt="n") # (as small pdf as possible)
75182 maechler 261
    ry <- range(y)
262
    xp <- par("yaxp")
263
    ## and indeed yaxp do cover the range(y) :
264
    stopifnot(xp[1] <= ry[1], ry[2] <= xp[2], xp[3] == 1)
265
    invisible(xp)
266
}
75196 maechler 267
if(interactive()) # not regularly, where pdf is stored
75182 maechler 268
plotNchk(y74) # gives 3 warnings; 1. from pretty(): "very small range"
269
plotNchk(y74[1:8]) # 3 warnings *and* no error anymore
270
plotNchk(y74[1:2]) #    (ditto)
77311 maechler 271
 
272
 
273
## dotchart(*, pch=., groups=*) -- PR#16953
78767 maechler 274
## dotchart(*, ylab=.) for groups;
275
g <- rep(1:3, each=2)
276
dotchart(VADeaths[1:2, 1:3], color=g, pch=g,
277
         ylab = "Grouping:  {Urbanity . Gender} x Age",
278
         xaxt="n", frame.plot=FALSE)
279
## now pch and colors match groups;
280
## ylab placement; group (row) labels show again
80947 maechler 281
 
282
 
283
## non-integer mgp[3] -- PR#18194
284
par(mar = c(5, 5, 5, 5))
285
plot.new()
286
plot.window(xlim = c(0, 5), ylim = 0:1)
287
if(dev.interactive()) {
288
    box(lty = 3)
289
    ## 'axis' puts line and labels in right place when 'mgp[3]' is integer
290
    mgp_bottom <- c(4, 2.5, 1) # 'mgp[1]' is arbitrary
291
    axis(1, at=c(1,4), mgp = mgp_bottom)
292
    mtext(c("labels", "line"), side = 1, line = mgp_bottom[2:3])
293
}
294
## Now, 'axis' puts line & labels in right place also when 'mgp[3]' is noninteger:
295
mgp_top <- c(4, 2.5, 0.9)
296
axis(3, at=c(1,4), mgp = mgp_top)
297
mtext(c("labels are here", "line"), line = mgp_top[2:3])
298
## They were one line too high in R <= 4.1.1