This function plots a ROC curve. It can accept many arguments to
tweak the appearance of the plot. Two syntaxes are possible: one
object of class “roc”, or either two vectors (response, predictor) or a
formula (response~predictor) as in the roc function.
Usage
## S3 method for class 'roc'
plot(x, ...)
## S3 method for class 'smooth.roc'
plot(x, ...)
## S3 method for class 'roc'
plot.roc(x, add=FALSE, reuse.auc=TRUE,
axes=TRUE, legacy.axes=FALSE,
# Generic arguments for par:
xlim=if(x$percent){c(100, 0)} else{c(1, 0)},
ylim=if(x$percent){c(0, 100)} else{c(0, 1)},
xlab=ifelse(x$percent, ifelse(legacy.axes, "100 - Specificity (%)", "Specificity (%)"),
ifelse(legacy.axes, "1 - Specificity", "Specificity")),
ylab=ifelse(x$percent, "Sensitivity (%)", "Sensitivity"),
asp=1,
mar=c(4, 4, 2, 2)+.1,
mgp=c(2.5, 1, 0),
# col, lty and lwd for the ROC line only
col=par("col"),
lty=par("lty"),
lwd=2,
type="l",
# Identity line
identity=!add,
identity.col="darkgrey",
identity.lty=1,
identity.lwd=1,
# Print the thresholds on the plot
print.thres=FALSE,
print.thres.pch=20,
print.thres.adj=c(-.05,1.25),
print.thres.col="black",
print.thres.pattern=ifelse(x$percent, "%.1f (%.1f%%, %.1f%%)", "%.3f (%.3f, %.3f)"),
print.thres.cex=par("cex"),
print.thres.pattern.cex=print.thres.cex,
print.thres.best.method=NULL,
print.thres.best.weights=c(1, 0.5),
# Print the AUC on the plot
print.auc=FALSE,
print.auc.pattern=NULL,
print.auc.x=ifelse(x$percent, 50, .5),
print.auc.y=ifelse(x$percent, 50, .5),
print.auc.adj=c(0,1),
print.auc.col=col,
print.auc.cex=par("cex"),
# Grid
grid=FALSE,
grid.v={if(is.logical(grid) && grid[1]==TRUE)
{seq(0, 1, 0.1) * ifelse(x$percent, 100, 1)}
else if(is.numeric(grid))
{seq(0, ifelse(x$percent, 100, 1), grid[1])} else {NULL}},
grid.h={if (length(grid) == 1) {grid.v}
else if (is.logical(grid) && grid[2]==TRUE)
{seq(0, 1, 0.1) * ifelse(x$percent, 100, 1)}
else if(is.numeric(grid))
{seq(0, ifelse(x$percent, 100, 1), grid[2])} else {NULL}},
grid.lty=3,
grid.lwd=1,
grid.col="#DDDDDD",
# Polygon for the AUC
auc.polygon=FALSE,
auc.polygon.col="gainsboro",
auc.polygon.lty=par("lty"),
auc.polygon.density=NULL,
auc.polygon.angle=45,
auc.polygon.border=NULL,
# Polygon for the maximal AUC possible
max.auc.polygon=FALSE,
max.auc.polygon.col="#EEEEEE",
max.auc.polygon.lty=par("lty"),
max.auc.polygon.density=NULL,
max.auc.polygon.angle=45,
max.auc.polygon.border=NULL,
# Confidence interval
ci=!is.null(x$ci),
ci.type=c("bars", "shape", "no"),
ci.col=ifelse(ci.type=="bars", par("fg"), "gainsboro"),
...)
## S3 method for class 'formula'
plot.roc(x, data, ...)
## Default S3 method:
plot.roc(x, predictor, ...)
## S3 method for class 'smooth.roc'
plot.roc(x, ...)
Arguments
x
a roc object from the roc function (for plot.roc.roc),
a formula (for plot.roc.formula) or a response vector (for
plot.roc.default).
predictor, data
arguments for the roc function.
add
if TRUE, the ROC curve will be added to an existing
plot. If FALSE (default), a new plot will be created.
reuse.auc
if TRUE (default) and the “roc” object
contains an “auc” field, re-use these specifications for the
plot (specifically print.auc, auc.polygon and
max.auc.polygon arguments). See details.
axes
a logical indicating if the plot axes must be drawn.
legacy.axes
a logical indicating if the specificity axis (x
axis) must be plotted as as decreasing “specificity”
(FALSE, the default) or increasing “1 - specificity”
(TRUE) as in most legacy software. This affects only the
axis, not the plot coordinates.
xlim, ylim, xlab, ylab, asp, mar, mgp
Generic arguments for the
plot. See plot and plot.window for more details. Only
used if add=FALSE.
col,lty, lwd
color, line type and line width for the ROC
curve. See par for more details.
type
type of plotting as in plot.
identity
logical: whether or not the identity line (no discrimination
line) must be displayed. Default: only on new plots.
identity.col, identity.lty, identity.lwd
color, line type and
line width for the identity line. Used only if identity=TRUE. See
par for more details.
print.thres
Should a selected set of thresholds be displayed on
the ROC curve? FALSE, NULL or “no”: no threshold is
displayed. TRUE or “best”: the threshold with the
highest sum sensitivity + specificity is plotted (this might be more
than one threshold). “all”: all the points of the ROC
curve. “local maximas”: all the local maximas. Numeric
vector: direct definition of the thresholds to display.
Note that on a smoothed ROC curve, only “best” is supported.
the plotting character (pch), text string
adjustment (adj), color (col) and character expansion factor (cex)
parameters for the printing of the thresholds. See points and
par for more details.
print.thres.pattern
the text pattern for the thresholds, as a
sprintf format. Three numerics are passed to sprintf:
threshold, specificity, sensitivity.
print.thres.pattern.cex
the character expansion factor (cex) for the
threshold text pattern. See par for more details.
print.thres.best.method, print.thres.best.weights
if
print.thres="best" or print.thres=TRUE, what method must be used to determine which
threshold is the best. See argument best.method and best.weights to
coords for more details.
print.auc
boolean. Should the numeric value of AUC be printed
on the plot?
print.auc.pattern
the text pattern for the AUC, as a
sprintf format. If NULL, a reasonable value is computed that
takes partial AUC, CI and percent into account. If the CI
of the AUC was computed, three numerics are passed to
sprintf: AUC, lower CI bound, higher CI bound. Otherwise, only AUC is
passed.
print.auc.x, print.auc.y
x and y position for the printing of
the AUC.
print.auc.adj, print.auc.cex, print.auc.col
the text
adjustment, character expansion factor and color for the printing of
the AUC. See par for more details.
grid
boolean or numeric vector of length 1 or 2. Should a
background grid be added to the plot? Numeric: show a grid with the
specified interval between each line; Logical: show the grid or
not. Length 1: same values are taken for horizontal and vertical
lines. Length 2: grid value for vertical (grid[1]) and horizontal
(grid[2]). Note that these values are used to compute grid.v and
grid.h. Therefore if you specify a grid.h and grid.v, it will be
ignored.
grid.v, grid.h
numeric. The x and y values at which a vertical
or horizontal line (respectively) must be drawn. NULL if no line
must be added.
grid.lty, grid.lwd, grid.col
the line type (lty), line width (lwd) and
color (col) of the lines of the grid. See par for
more details. Note that you can pass vectors of length 2, in which
case it specifies the vertical (1) and horizontal (2) lines.
auc.polygon
boolean. Whether or not to display the area as a
polygon.
color (col), line type
(lty), density, angle and border for the maximum AUC polygon. See
polygon and par for more details.
ci
boolean. Should we plot the confidence intervals?
ci.type, ci.col
type and col arguments for
plot.ci. The special value “no” disables the plotting of confidence intervals.
...
further arguments passed to or from other methods,
especially arguments for roc and plot.roc.roc when calling
plot.roc.default or plot.roc.formula. Note that the
plot argument for roc is not allowed.
Arguments for auc and graphical functions
plot, abline, polygon,
points, text and plot.ci
if applicable.
Details
This function is typically called from roc when plot=TRUE (not by
default). plot.roc.formula and plot.roc.default are convenience methods
that build the ROC curve (with the roc function) before
calling plot.roc.roc. You can pass them arguments for both
roc and plot.roc.roc. Simply use plot.roc
that will dispatch to the correct method.
The plotting is done in the following order:
A new plot is created if add=FALSE.
The grid is added if grid.v and grid.h are not NULL.
The maximal AUC polygon is added if max.auc.polygon=TRUE.
The CI shape is added if ci=TRUE, ci.type="shape" and x$ci isn't a “ci.auc”.
The AUC polygon is added if auc.polygon=TRUE.
The identity line if identity=TRUE.
The actual ROC line is added.
The CI bars are added if ci=TRUE, ci.type="bars" and x$ci isn't a “ci.auc”.
The selected thresholds are printed if print.thres is TRUE or numeric.
The AUC is printed if print.auc=TRUE.
Graphical functions are called with suppressWarnings.
Value
This function returns a list of class “roc” invisibly. See roc for more details.
AUC specification
For print.auc, auc.polygon and max.auc.polygon
arguments, an AUC specification is
required. By default, the total AUC is plotted, but you may want a
partial AUCs. The specification is defined by:
the “auc” field in the “roc” object if
reuse.auc is set to TRUE (default). It is naturally
inherited from any call to roc and fits most cases.
passing the specification to auc with ...
(arguments partial.auc, partial.auc.correct and
partial.auc.focus). In this case, you must ensure either that
the roc object do not contain an auc field (if
you called roc with auc=FALSE), or set
reuse.auc=FALSE.
If reuse.auc=FALSE the auc function will always
be called with ... to determine the specification, even if
the “roc” object do contain an auc field.
As well if the “roc” object do not contain an auc
field, the auc function will always be called with
... to determine the specification.
Warning: if the roc object passed to plot.roc contains an auc
field and reuse.auc=TRUE, auc is not called and
arguments such as partial.auc are silently ignored.
References
Xavier Robin, Natacha Turck, Alexandre Hainard, et al.
(2011) “pROC: an open-source package for R and S+ to analyze and
compare ROC curves”. BMC Bioinformatics, 7, 77.
DOI: 10.1186/1471-2105-12-77.
See Also
roc, auc, ci
Examples
data(aSAH)
# Syntax (response, predictor):
plot.roc(aSAH$outcome, aSAH$s100b)
# With a roc object:
rocobj <- roc(aSAH$outcome, aSAH$s100b)
# identical:
plot(rocobj)
plot.roc(rocobj)
# Add a smoothed ROC:
plot.roc(smooth(rocobj), add=TRUE, col="blue")
legend("bottomright", legend=c("Empirical", "Smoothed"),
col=c(par("fg"), "blue"), lwd=2)
# With more options:
plot(rocobj, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),
grid.col=c("green", "red"), max.auc.polygon=TRUE,
auc.polygon.col="blue", print.thres=TRUE)
# To plot a different partial AUC, we need to ignore the existing value
# with reuse.auc=FALSE:
plot(rocobj, print.auc=TRUE, auc.polygon=TRUE, partial.auc=c(1, 0.8),
partial.auc.focus="se", grid=c(0.1, 0.2), grid.col=c("green", "red"),
max.auc.polygon=TRUE, auc.polygon.col="blue", print.thres=TRUE,
reuse.auc=FALSE)
# Add a line to the previous plot:
plot.roc(aSAH$outcome, aSAH$wfns, add=TRUE)
# Alternatively, you can get the plot directly from roc():
roc(aSAH$outcome, aSAH$s100b, plot=TRUE)