r - examples - labels in boxplot
Funciones disponibles para Tufte boxplots en R? (5)
Aparentemente, solo quería una versión vertical, así que tomé el código de panel.bwplot, eliminé todos los elementos no esenciales, como la caja y la tapa, y puse horizontal = FALSO en los argumentos y creé una función panel.tuftebxp. También establezca el valor de los puntos en la mitad del valor predeterminado. Aún quedan muchas opciones que podrían ajustarse a sus gustos. Los nombres de los factores "numéricos" para "Tiempo" parecen descuidados, pero creo que la "prueba de concepto" es clara y puede limpiar lo que es importante para usted:
panel.tuftebxp <-
function (x, y, box.ratio = 1, box.width = box.ratio/(1 + box.ratio), horizontal=FALSE,
pch = box.dot$pch, col = box.dot$col,
alpha = box.dot$alpha, cex = box.dot$cex, font = box.dot$font,
fontfamily = box.dot$fontfamily, fontface = box.dot$fontface,
fill = box.rectangle$fill, varwidth = FALSE, notch = FALSE,
notch.frac = 0.5, ..., levels.fos = if (horizontal) sort(unique(y)) else sort(unique(x)),
stats = boxplot.stats, coef = 1.5, do.out = TRUE, identifier = "bwplot")
{
if (all(is.na(x) | is.na(y)))
return()
x <- as.numeric(x)
y <- as.numeric(y)
box.dot <- trellis.par.get("box.dot")
box.rectangle <- trellis.par.get("box.rectangle")
box.umbrella <- trellis.par.get("box.umbrella")
plot.symbol <- trellis.par.get("plot.symbol")
fontsize.points <- trellis.par.get("fontsize")$points
cur.limits <- current.panel.limits()
xscale <- cur.limits$xlim
yscale <- cur.limits$ylim
if (!notch)
notch.frac <- 0
#removed horizontal code
blist <- tapply(y, factor(x, levels = levels.fos), stats,
coef = coef, do.out = do.out)
blist.stats <- t(sapply(blist, "[[", "stats"))
blist.out <- lapply(blist, "[[", "out")
blist.height <- box.width
if (varwidth) {
maxn <- max(table(x))
blist.n <- sapply(blist, "[[", "n")
blist.height <- sqrt(blist.n/maxn) * blist.height
}
blist.conf <- if (notch)
sapply(blist, "[[", "conf")
else t(blist.stats[, c(2, 4), drop = FALSE])
ybnd <- cbind(blist.stats[, 3], blist.conf[2, ], blist.stats[,
4], blist.stats[, 4], blist.conf[2, ], blist.stats[,
3], blist.conf[1, ], blist.stats[, 2], blist.stats[,
2], blist.conf[1, ], blist.stats[, 3])
xleft <- levels.fos - blist.height/2
xright <- levels.fos + blist.height/2
xbnd <- cbind(xleft + notch.frac * blist.height/2, xleft,
xleft, xright, xright, xright - notch.frac * blist.height/2,
xright, xright, xleft, xleft, xleft + notch.frac *
blist.height/2)
xs <- cbind(xbnd, NA_real_)
ys <- cbind(ybnd, NA_real_)
panel.segments(rep(levels.fos, 2), c(blist.stats[, 2],
blist.stats[, 4]), rep(levels.fos, 2), c(blist.stats[,
1], blist.stats[, 5]), col = box.umbrella$col, alpha = box.umbrella$alpha,
lwd = box.umbrella$lwd, lty = box.umbrella$lty, identifier = paste(identifier,
"whisker", sep = "."))
if (all(pch == "|")) {
mult <- if (notch)
1 - notch.frac
else 1
panel.segments(levels.fos - mult * blist.height/2,
blist.stats[, 3], levels.fos + mult * blist.height/2,
blist.stats[, 3], lwd = box.rectangle$lwd, lty = box.rectangle$lty,
col = box.rectangle$col, alpha = alpha, identifier = paste(identifier,
"dot", sep = "."))
}
else {
panel.points(x = levels.fos, y = blist.stats[, 3],
pch = pch, col = col, alpha = alpha, cex = cex,
identifier = paste(identifier,
"dot", sep = "."))
}
panel.points(x = rep(levels.fos, sapply(blist.out, length)),
y = unlist(blist.out), pch = plot.symbol$pch, col = plot.symbol$col,
alpha = plot.symbol$alpha, cex = plot.symbol$cex*0.5,
identifier = paste(identifier, "outlier", sep = "."))
}
bwplot(weight ~ Diet + Time + Chick, data=cw, panel=
function(x,y, ...) panel.tuftebxp(x=x,y=y,...))
Tengo algunos datos que he dividido en grupos suficientes para que las gráficas de caja parezcan muy concurridas. Tufte tiene sus propios diagramas de caja en los que básicamente suelta todo o la mitad de la caja, como esto:
Algunos datos de muestra:
cw <- transform(ChickWeight,
Time = cut(ChickWeight$Time,4)
)
cw$Chick <- as.factor( sample(LETTERS[seq(3)], nrow(cw), replace=TRUE) )
levels(cw$Diet) <- c("Low Fat","Hi Fat","Low Prot.","Hi Prot.")
Quiero un diagrama de caja de peso para cada grupo de Diet * Time * Chick.
Tuve este problema surgió hace años, y reuní una solución utilizando gráficos de cuadrícula, que publicaré en un momento. Pero al resolver este nuevo (y similar) problema, me pregunto si hay una manera común de hacerlo en lugar de arreglar mi ejemplo de kludged.
Dejando de lado, estas parecen estar entre las menos queridas de las creaciones de Tufte, pero realmente me gustan por mostrar densamente patrones de distribuciones en un gran número de grupos, y los usaría más si hubiera una buena función para ellos en ggplot2 o celosía.
Aquí está la solución ggplot
habitual (o, más bien, un truco con posibilidades de elegancia)
require(ggplot2)
# melt the data frame
cw2 = melt(cw, id = ''weight'')
# create a data frame with boxplot stats
cw3 = ddply(cw2, .(value, variable), function(df) boxplot.stats(df$weight)$stats)
# generate the plot
ggplot(cw2, aes(value, weight)) +
geom_boxplot(fill = ''gray90'', colour = ''gray90'', alpha = 0) +
geom_segment(data = cw3, aes(xend = value, y = V1, yend = V2)) +
geom_segment(data = cw3, aes(xend = value, y = V4, yend = V5)) +
geom_point(data = cw3, aes(y = V3), size = 3) +
facet_wrap(~ variable, scales = ''free_x'', nrow = 1)
Aquí está mi función muy torpe para esto. Desafortunadamente, aunque hace referencia a un panel.tuftebox, escribí este código en mis primeros meses de aprendizaje de R para un propósito muy específico (y, por lo tanto, lamentablemente, sin la intención de generalizarlo), y por lo tanto nunca se escribió como un documento aparte. función del panel.
library(lattice)
library(taRifx)
compareplot(~weight | Diet * Time * Chick,
data.frame=cw ,
main = "Chick Weights",
box.show.mean=FALSE,
box.show.whiskers=FALSE,
box.show.box=FALSE
)
Aquí hay una solución sin usar ningún paquete, simplemente manipulando los parámetros gráficos de parcelas de caja. Mi sugerencia es la más cercana a @DWin, pero eliminando el color y los ejes, y utilizando solo unas pocas líneas de código. Ambas sugerencias de @ gsk3 y @Ramnath son muy buenas y mucho más avanzadas que las mías, pero si puedo comentar, no abordan la filosofía principal de Tufte. Si elimináramos el fondo gris, las "barras de la prisión" blancas y los colores innecesarios, todas las soluciones mencionadas anteriormente ganarían en claridad, simplicidad y equilibrio correcto entre datos y tinta.
Los créditos deben ir a los creadores de PerformanceAnalytics
, que incluyeron cute chart.Boxplot
wrapper inspirado en el trabajo de Tufte. Simplemente extraje algunos elementos de la función para que sea aún más simple. Simplemente adjunte los datos de muestra ''cw'' anteriores de @ gsk3.
attach(cw)
par(mfrow=c(1,3))
boxplot(weight~Time, horizontal = F, main = "", xlab="Time", ylab="Weight",
pars = list(boxcol = "white", medlty = "blank", medpch=16, medcex = 1.3,
whisklty = c(1, 1), staplelty = "blank", outcex = 0.5), axes = FALSE)
axis(1,at=1:4,label=c(1:4))
axis(2)
boxplot(weight~Chick, horizontal = F, main = "", xlab = "Chick",
ylab = "", pars = list(boxcol = "white", medlty = "blank", medpch=16,
medcex = 1.3, whisklty = c(1, 1), staplelty = "blank", outcex = 0.5),
axes = FALSE)
axis(1,at=1:3,label=c("A","B","C"))
boxplot(weight~Diet, horizontal = F, main = "", xlab = "Diet", ylab = "",
pars = list(boxcol = "white", medlty = "blank", medpch=16, medcex = 1.3,
whisklty = c(1, 1), staplelty = "blank", outcex = 0.5), axes = FALSE)
axis(1,at=1:4,label=c("LoFat","HiFat","LoProt","HiProt"))
Hay funciones para hacer algunos gráficos de estilo Tufte en el paquete ggthemes
de Jeffrey Arnold , disponible en github . El paquete es un montón de temas para ggplot
e incluye:
geom_tufterangeframe
: marco de rango de Tufte
geom_tufteboxplot
: geom_tufteboxplot
de caja de Tufte
theme_tufte
: una tinta mínima basada en la visualización visual de información cuantitativa de Tufte.
Aquí hay un ejemplo del diagrama de caja de Tufte minimal del README del paquete en github: