File: plotqq.R

package info (click to toggle)
r-cran-plotmo 3.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,400 kB
  • sloc: sh: 13; makefile: 2
file content (132 lines) | stat: -rw-r--r-- 5,756 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# plotqq.R

plotmo_qq <- function(rinfo, info, nfigs,
                      grid.col, smooth.col,
                      id.n, iresids, npoints,
                      force.auto.resids.ylim,
                      ...)
{
    old.pty <- par("pty")
    par(pty="s") # square
    on.exit(par(pty=old.pty))
    # we figure out the shape of the qq line with all resids but
    # plot only npoints points (selecting them with iresids)
    resids <- rinfo$scale * rinfo$resids
    # qqnorm sets NAs in trans.resids (leverage==1) to NA in
    # qq$x and qq$y, and thus NAs don't get plotted (R PR#3750)
    main <- dota("main", DEF=sprint("%s QQ", rinfo$name), ...)
    qq <- qqnorm(resids, main=main, plot.it=FALSE)
    id.indices <- get.id.indices(resids, id.n)
    xlim <- NULL
    ylim <- NULL
    if(nfigs == 1) # user can set xlim only if this is the only figure
        xlim <- dota("xlim", DEF=xlim, ...)
    if(!force.auto.resids.ylim)
        ylim <- dota("ylim", DEF=ylim, ...)
    xlim <- dota("qq.xlim", DEF=xlim, ...)
    ylim <- dota("qq.ylim", DEF=ylim, ...)
    if(!is.specified(xlim) && !is.null(id.indices)) { # extra space for point labs?
        min <- min(qq$x, na.rm=TRUE)
        max <- max(qq$x, na.rm=TRUE)
        xlim <- c(min - .1 * (max - min), max + .1 * (max - min))
    }
    if(!is.specified(ylim)) {
        min <- min(qq$y, na.rm=TRUE)
        max <- max(qq$y, na.rm=TRUE)
        ylim <- c(min, max)
        if(!is.null(id.indices))    # extra space for point labs?
            ylim <- c(min - .05 * (max - min), max + .05 * (max - min))
        if(info)                    # extra space for density plot?
            ylim[1] <- ylim[1] - .1 * (max - min)
    }
    xlim <- fix.lim(xlim)
    ylim <- fix.lim(ylim)

    # allow col.response as an argname for compat with old plotmo
    pt.col <- dota("col.response col.resp", DEF=1, ...)
    pt.col <- dota("pt.col col.points col.point col.residuals col.resid col",
                   EX=c(0,1,1,1,1,1), DEF=pt.col, NEW=1, ...)
    pt.col <- dota("qq.col col.residuals col.resid col",
                   EX=c(0,1,1,1), DEF=pt.col, NEW=1, ...)
    # recycle
    pt.col <- repl(pt.col, length(resids))
    pt.cex <- dota("response.cex cex.response", DEF=1, ...)
    pt.cex <- dota("pt.cex cex.points cex.point cex",
                   EX=c(0,1,1,1), DEF=pt.cex, NEW=1, ...)
    pt.cex <- dota("qq.cex cex.qq cex.residuals",
                   EX=c(0,1,1), DEF=pt.cex, NEW=1, ...)
    pt.cex <- pt.cex * pt.cex(length(resids), npoints)
    pt.cex <- repl(pt.cex, length(resids))

    pt.pch <- dota("response.pch pch.response", DEF=20, ...)
    pt.pch <- dota(
        "qq.pch pt.pch pch.points pch.point pch.residuals pch",
        EX=c(1,0,0,1,1,1), DEF=pt.pch, NEW=1, ...)
    pt.pch <- repl(pt.pch, length(resids))

    ylab <- rinfo$name
    ylab <- sprint("%s Quantiles", ylab)
    drop.line.col <- function(..., qqline.col=NA, qqline.lwd=NA, qqline.lty=NA)
    {
        call.plot(graphics::plot, PREFIX="qq.",
                  force.x    = qq$x[iresids],
                  force.y    = qq$y[iresids],
                  force.col  = pt.col[iresids],
                  force.cex  = pt.cex[iresids],
                  force.pch  = pt.pch[iresids],
                  force.main = main,
                  force.xlab = "Normal Quantiles",
                  force.ylab = ylab,
                  force.xlim = xlim,
                  force.ylim = ylim,
                  ...)
    }
    drop.line.col(...)
    if(is.specified(grid.col))
        grid(col=grid.col, lty=1)
    qqline.col <- dota("qqline.col", DEF=1, ...)
    qqline.lwd <- dota("qqline.lwd", DEF=1, ...)
    qqline.lty <- dota("qqline.lty", DEF=3, ...)
    if(is.specified(qqline.col) &&
       is.specified(qqline.lwd) &&
       is.specified(qqline.lty))
        call.plot(qqline, force.y=resids,
                  force.col=qqline.col, force.lwd=qqline.lwd, force.lty=qqline.lty, ...)
    if(info) {
        # draw actual and theoretical density along the bottom
        usr <- par("usr") # xmin, xmax, ymin, ymax
        scale <- .1 * (usr[4] - usr[3]) / (max(qq$y) - min(qq$y))
        draw.density.along.the.bottom(qq$x, den.col=smooth.col, scale=scale, ...)
        draw.density.along.the.bottom(
            resids / sd(resids, na.rm=TRUE), # TODO correct?
            scale=scale, ...)
        legend("bottomright", inset=c(0,.06),
               legend=c("actual", "normal"),
               cex=.8, lty=1, col=c("gray57", smooth.col),
               box.col="white", bg="white", x.intersp=.2, seg.len=1.5)
    }
    if(is.specified(grid.col) || is.specified(qqline.col) || info) {
        # replot box and points because they may have been obscured
        box()
        drop.line.col <- function(..., qqline.col=NA, qqline.lwd=NA, qqline.lty=NA)
        {
            call.plot(graphics::points, PREFIX="qq.",
                      force.x    = qq$x[iresids],
                      force.y    = qq$y[iresids],
                      force.col  = pt.col[iresids],
                      force.cex  = pt.cex[iresids],
                      force.pch  = pt.pch[iresids],
                      ...)
        }
        drop.line.col()
    }
    if(!is.null(id.indices))
        plotrix::thigmophobe.labels(
            x      = qq$x[id.indices], y=qq$y[id.indices],
            labels = rinfo$labs[id.indices],
            offset = .33, xpd=NA,
            font   = dota("label.font", DEF=1, ...)[1],
            cex    = .8 * dota("label.cex", DEF=1, ...)[1],
            col    = dota("label.col",
                      DEF=if(is.specified(smooth.col)) smooth.col else 2, ...)[1])
}