Nothing
# fancy scatterplots (J. Fox)
# 2010-09-05: J. Fox: changed color choice
# 2010-09-16: fixed point color when col is length 1
# 2010-12-19: J. Fox: added argument legend.coords to place legend.
# 2011-01-15: J. Fox: If x is a factor, calls Boxplot()
# 2011-03-08: J. Fox: changed col argument
# 2012-04-18: J. Fox: fixed labels argument in scatterplot.formula().
# 2012-04-24: J. Fox: further fix to labels
# 2012-09-12: J. Fox: modified treatment of smoother; added loessLine(), gamLine(), quantregLine().
# 2012-09-17: S. Weisberg: smoothers moved to scatterplotSmoothers.R, defaults changed
# 2012-09-19: J. Fox: restored smooth and span arguments for backwards compatibility
# 2013-02-07: S. Weisberg: modifed call to showLabels to work correctly with groups
# 2014-09-04: J. Fox: empty groups produce warning rather than error
# 2015-07-17: J. Fox: improved above-plot legends.
# 2015-08-05: J. Fox: fixed sp()
# 2017-01-09: J. Fox: consolidated many arguments into id, smooth, and legend;
# 2017-02-09: J. Fox: consolidated ellipse arguments; small fixes.
# 2017-02-17: S. Weisberg: removed many arguments that can be passed via other argument or ...
# 2017-02-22: J. Fox: improvement to col argument
# 2017-02-28: S. Weisberg: showLabels bug-fix.
# 2016-02-28: S. Weisberg: added cex arg to the legend
# 2017-04-14: S. Weisberg: changed default colors so points and corresponding lines always have same color
# 2017-05-08: S. Weisberg changed col=carPalette()
# 2017-11-30: substitute carPalette() for palette(). J. Fox
# 2017-12-07: J. Fox: added fill, fill.alpha subargs to ellipse arg, suggestion of Michael Friendly.
# 2018-03-23: J. Fox: fix ellipses when log-axes used by groups; fix interactive point identification by groups.
# 2018-04-02: J. Fox: warning rather than error for too few colors.
# 2018-04-12: J. Fox: fixed error produced when groups not a factor, reported by Alexandre Courtiol.
# 2018-05-19: J. Fox: fixed bug when legend=FALSE, reported by Castor Guisande.
# 2018-06-25: S. Weisberg made the argument 'var' an alias of 'spread'
# 2019-01-15: J. Fox: make scatterplot.formula() more robust
# 2020-05-03: J. Fox: make marginal boxplots work with xlim and ylim (problem reported by Yousri Fanous)
# 2021-04-05: J. Fox: don't explicitly dispatch on argument x in generic
reg <- function(reg.line, x, y, col, lwd, lty, log.x, log.y){
if(log.x) x <- log(x)
if(log.y) y <- log(y)
mod <- reg.line(y ~ x)
y.hat <- fitted.values(mod)
x <- model.matrix(mod)[, 2]
min <- which.min(x)
max <- which.max(x)
if (!log.x){
x1 <- x[min]
x2 <- x[max]
}
else {
x1 <- exp(x[min])
x2 <- exp(x[max])
}
if (!log.y){
y1 <- y.hat[min]
y2 <- y.hat[max]
}
else {
y1 <- exp(y.hat[min])
y2 <- exp(y.hat[max])
}
lines(c(x1, x2), c(y1, y2), lwd=lwd, col=col, lty=lty)
}
find.legend.columns <- function(n, target=min(4, n)){
rem <- n %% target
if (rem != 0 && rem < target/2) target <- target - 1
target
}
scatterplot <- function(x, ...){
UseMethod("scatterplot")
}
scatterplot.formula <- function (formula, data, subset, xlab, ylab,
id=FALSE, legend=TRUE, ...) {
na.save <- options(na.action=na.omit)
on.exit(options(na.save))
na.pass <- function(dframe) dframe
id <- if (is.logical(id)){
if (isTRUE(id)) list()
else FALSE
}
else as.list(id)
legend <- applyDefaults(legend, defaults=list(), type="legend")
m <- match.call(expand.dots=FALSE)
if (is.matrix(eval(m$data, sys.frame(sys.parent()))))
m$data <- as.data.frame(data)
m$na.action <- na.pass
m$legend <- m$id <- m$xlab <- m$ylab <- m$... <- NULL
m[[1]] <- as.name("model.frame")
if (!inherits(formula, "formula") | length(formula) != 3)
stop("invalid formula")
formula <- as.character(c(formula))
formula <- as.formula(sub("\\|", "+", formula))
m$formula <- formula
if (missing(data)){
X <- na.omit(eval(m, parent.frame()))
if (!isFALSE(id) && is.null(id$labels)) id$labels <- gsub("X", "", row.names(X))
if (is.factor(X[, 2]) && !is.list(id)) id <- list(labels=gsub("X", "", row.names(X)))
}
else{
X <- eval(m, parent.frame())
if (!isFALSE(id) && is.null(id$labels)) id$labels <- row.names(X)
if (is.factor(X[, 2]) && !is.list(id)) id <- list(labels=row.names(X))
}
names <- names(X)
if (missing(xlab)) xlab <- names[2]
if (missing(ylab)) ylab <- names[1]
X[, 1] <- as.vector(X[, 1])
if (!is.factor(X[, 2])) X[, 2] <- as.vector(X[, 2])
if (ncol(X) == 2) scatterplot(X[,2], X[,1], xlab=xlab, ylab=ylab,
id=id, ...)
else {
if (!isFALSE(legend)){
if (is.null(legend$title)) legend$title <- names[3]
}
scatterplot(X[,2], X[,1], groups=X[,3], xlab=xlab, ylab=ylab,
legend=legend, id=id, ...)
}
}
scatterplot.default <- function(x, y, boxplots=if (by.groups) "" else "xy",
regLine=TRUE, legend=TRUE, id=FALSE, ellipse=FALSE, grid=TRUE,
smooth=TRUE,
groups, by.groups=!missing(groups),
xlab=deparse(substitute(x)), ylab=deparse(substitute(y)),
log="", jitter=list(), cex=par("cex"),
col=carPalette()[-1], pch=1:n.groups,
reset.par=TRUE, ...){
force(col)
dots <- list(...)
xlim <- dots$xlim
ylim <- dots$ylim
id <- applyDefaults(id, defaults=list(method="mahal", n=2, cex=1, col=carPalette()[-1], location="lr"), type="id")
legend <- applyDefaults(legend, defaults=list(title=deparse(substitute(groups)), inset=0.02, cex=1))
legend.plot <- !(isFALSE(legend) || missing(groups))
if (legend.plot){
legend.title <- legend$title
legend.cex <- legend$cex
}
if (isFALSE(id)){
id.n <- 0
id.method <- "mahal"
labels <- id.cex <- id.col <- id.location <- NULL
}
else{
labels <- id$labels
id.method <- id$method
id.n <- if ("identify" %in% id.method) Inf else id$n
id.cex <- id$cex
id.col <- if (by.groups) id$col else id$col[1]
id.location <- id$location
}
smoother.args <- applyDefaults(smooth, defaults=list(smoother=loessLine, spread=!by.groups, lty.smooth=2, lty.spread=4), type="smooth")
if (!isFALSE(smoother.args)) {
# check for an argument 'var' in smoother.args.
if(!is.null(smoother.args$var)) smoother.args$spread <- smoother.args$var
# end change
smoother <- smoother.args$smoother
spread <- if(is.null(smoother.args$spread)) TRUE else smoother.args$spread
smoother.args$smoother <- NULL
}
else smoother <- "none"
ellipse.args <- applyDefaults(ellipse, defaults=list(levels=c(.5, .95), robust=TRUE, fill=TRUE, fill.alpha=0.2, type="ellipse"))
if (!is.logical(ellipse)) ellipse <- TRUE
if (!isFALSE(ellipse.args)){
levels <- ellipse.args$levels
robust <- ellipse.args$robust
fill <- ellipse.args$fill
fill.alpha <- ellipse.args$fill.alpha
}
n.groups <- if (by.groups) {
if (!is.factor(groups)) groups <- as.factor(groups)
length(levels(groups))
}
else 1
regLine.args <- applyDefaults(regLine, defaults=list(method=lm, lty=1, lwd=2,
col=rep(col, n.groups), type="regLine"))
if(!isFALSE(regLine.args)) {
if(length(regLine.args$col) < n.groups){
regLine.args$col <- rep(regLine.args$col, n.groups)
}
}
logged <- function(axis=c("x", "y")){
axis <- match.arg(axis)
0 != length(grep(axis, log))
}
hbox <- function(x){
if (logged("x")){
log.x <- "x"
.x <- log(x)
}
else {
log.x <- ""
.x <- x
}
plot(x, seq(0, 1, length=length(x)), type="n", axes=FALSE, xlab="", ylab="", log=log.x, xlim=xlim)
res <- boxplot.stats(.x, coef = 1.5, do.conf=FALSE)
if (logged("x")){
res$stats <- exp(res$stats)
if (!is.null(res$out)) res$out <- exp(res$out)
}
LW <- res$stats[1]
Q1 <- res$stats[2]
M <- res$stats[3]
Q3 <- res$stats[4]
UW <- res$stats[5]
lines(c(Q1, Q1, Q3, Q3, Q1), c(0, 1, 1, 0, 0))
lines(c(M, M), c(0, 1))
lines(c(LW, Q1), c(.5, .5))
lines(c(Q3, UW), c(.5, .5))
if (!is.null(res$out)) points(res$out, rep(.5, length(res$out)), cex=cex)
}
vbox <- function(y){
if (logged("y")){
log.y <- "y"
.y <- log(y)
}
else {
log.y <- ""
.y <- y
}
plot(seq(0, 1, length=length(y)), y, type="n", axes=FALSE, xlab="", ylab="", log=log.y, ylim=ylim)
res <- boxplot.stats(.y, coef = 1.5, do.conf=FALSE)
if (logged("y")){
res$stats <- exp(res$stats)
if (!is.null(res$out)) res$out <- exp(res$out)
}
LW <- res$stats[1]
Q1 <- res$stats[2]
M <- res$stats[3]
Q3 <- res$stats[4]
UW <- res$stats[5]
lines(c(0, 1, 1, 0, 0), c(Q1, Q1, Q3, Q3, Q1))
lines(c(0, 1), c(M, M))
lines(c(.5, .5), c(LW, Q1))
lines(c(.5, .5), c(Q3, UW))
if (!is.null(res$out)) points(rep(.5, length(res$out)), res$out, cex=cex)
}
# force(by.groups)
id <- as.list(id)
if (is.null(labels)){
labels <- if (is.null(names(y)))
seq(along=y)
else names(y)
}
if (length(labels) != length(y)) stop("labels argument is the wrong length")
if (is.factor(x)) {
if (!(id.method %in% c("y", "identify", "none"))) id.method <- "y"
return(Boxplot(y, x, id.method="y", labels=labels, xlab=xlab, ylab=ylab))
}
mar <- par("mar")
mfcol <- par("mfcol")
if (reset.par) on.exit(par(mar=mar, mfcol=mfcol))
if( FALSE == boxplots) boxplots <- ""
if (!missing(groups)){
data <- na.omit(data.frame(groups, x, y, labels, stringsAsFactors=FALSE))
groups <- data[ , 1]
# if (!is.factor(groups)) groups <- as.factor(groups)
.x <- data[,2]
.y <- data[,3]
labels <- data[,4]
legend.columns <- if (legend.plot) legend$columns else 0
top <- if (legend.plot && is.null(legend$coords)){
if (is.null(legend.columns)) legend.columns <- find.legend.columns(nlevels(groups))
4 + ceiling(nlevels(groups))/legend.columns
}
else mar[3]
if (legend.plot && !is.null(legend$coords) && is.null(legend.columns)){
legend.columns <- 1
}
}
else {
.x <- x
.y <- y
top <- mar[3]
groups <- factor(rep(1, length(.x)))
}
xbox <- length(grep("x", boxplots)) > 0
ybox <- length(grep("y", boxplots)) > 0
if (xbox && ybox)
layout(matrix(c(1, 0, 3, 2), 2, 2),
widths = c(5, 95),
heights= c(95, 5))
else if (ybox)
layout(matrix(c(1, 2),1, 2),
widths = c(5, 95),
heights= 100)
else if (xbox)
layout(matrix(c(2, 1), 2, 1),
widths = 100,
heights= c(95, 5))
else layout (matrix(1, 1, 1),
widths=100, heights=100)
par(mar=c(mar[1], 0, top, 0))
if (ybox > 0) vbox(.y)
par(mar=c(0, mar[2], 0, mar[4]))
if (xbox > 0) hbox(.x)
par(mar=c(mar[1:2], top, mar[4]))
plot(.x, .y, xlab=xlab, ylab=ylab, log=log, cex=cex,
type="n", ...)
if(grid){
grid(lty=1, equilogs=FALSE)
box()}
if (n.groups > length(col)) {
warning("number of groups exceeds number of available colors\n colors are recycled")
col <- rep(col, n.groups)
}
if (length(col) == 1) col <- rep(col, 3)
indices <- NULL
range.x <- if (logged("x")) range(log(.x), na.rm=TRUE) else range(.x, na.rm=TRUE)
counts <- table(groups)
if (any(counts == 0)){
levels <- levels(groups)
warning("the following groups are empty: ", paste(levels[counts == 0], collapse=", "))
}
for (i in 1:n.groups){
if (counts[i] == 0) next
subs <- groups == levels(groups)[i]
points(if (is.null(jitter$x) || jitter$x == 0) .x[subs] else jitter(.x[subs], factor=jitter$x),
if (is.null(jitter$y) || jitter$y == 0) .y[subs] else jitter(.y[subs], factor=jitter$y),
pch=pch[i], col=col[if (n.groups == 1) 1 else i], cex=cex)
if (by.groups){
if (is.function(smoother))
smoother(.x[subs], .y[subs], col=col[i],
log.x=logged("x"), log.y=logged("y"), spread=spread, smoother.args=smoother.args)
if (!isFALSE(regLine.args)) reg(regLine.args$method, .x[subs], .y[subs], lty=regLine.args$lty,
lwd=regLine.args$lwd, log.x=logged("x"), log.y=logged("y"), col=
regLine.args$col[i])
if (ellipse) {
X <- na.omit(data.frame(x=.x[subs], y=.y[subs]))
if (logged("x")) X$x <- log(X$x)
if (logged("y")) X$y <- log(X$y)
with(X, dataEllipse(x, y, plot.points=FALSE, lwd=1, log=log,
levels=levels, col=col[i], robust=robust,
fill=fill, fill.alpha=fill.alpha))
}
if (id.method[1] != "identify")
indices <- c(indices,
showLabels(.x[subs], .y[subs], labels=labels[subs], method=id.method,
n=id.n, cex=id.cex, col=col[i], location=id.location,
all=list(labels=labels, subs=subs)))
}}
if (!by.groups){
if (is.function(smoother)) smoother(.x, .y, col=col[1],
log.x=logged("x"), log.y=logged("y"), spread, smoother.args=smoother.args)
if (!isFALSE(regLine.args)) reg(regLine.args$method, .x, .y, lty=regLine.args$lty, lwd=regLine.args$lwd,
log.x=logged("x"), log.y=logged("y"), col=regLine.args$col[1])
if (ellipse) {
X <- na.omit(data.frame(x=.x, y=.y))
if (logged("x")) X$x <- log(X$x)
if (logged("y")) X$y <- log(X$y)
with(X, dataEllipse(x, y, plot.points=FALSE, lwd=1, log=log, levels=levels, col=col[1],
robust=robust, fill=fill, fill.alpha=fill.alpha))
}
if (id.method[1] != "identify") indices <- showLabels(
.x, .y, labels=labels,
method=id.method, n=id.n, cex=id.cex, col=id.col, location=id.location)
}
if (legend.plot) {
xpd <- par(xpd=TRUE)
on.exit(par(xpd=xpd), add=TRUE)
usr <- par("usr")
legend.coords <- if (is.null(legend$coords)){
legend.x <- if (logged("x")) 10^(usr[1]) else usr[1]
legend.y <- if (logged("y")) 10^(usr[4] + 1.2*top*strheight("x")) else usr[4] + 1.2*top*strheight("x")
list(x=legend.x, y=legend.y)
}
else legend$coords
legend(legend.coords, legend=levels(groups)[counts > 0],
pch=pch[counts > 0], col=col[1:n.groups][counts > 0], cex=legend.cex, #pt.cex=cex, cex=cex, #cex=cex.lab,
title=legend.title, bg="white", ncol=legend.columns, inset=legend$inset)
}
if (id.method[1] == "identify") indices <- showLabels(.x, .y, labels,
method=id.method, n=length(.x), cex=id.cex, col="black", id.location=id.location)
if (is.null(indices)) invisible(indices) else if (is.numeric(indices)) sort(indices) else indices
}
sp <- function(x, ...) UseMethod("scatterplot")
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.