Por fin después de tanto trabajar pudimos dar con la solución de este asunto que muchos usuarios de nuestra web han presentado. Si deseas compartir algo más no dudes en aportar tu comentario.
Una solución sencilla sería trazar primero las barras de error:
p +
geom_errorbar(limits, position = dodge, width=0.25) +
geom_bar(position = dodge, stat = "identity")
El consejo de Henrik es excelente en este caso, pero te sugiero que eches un vistazo a dónde se establecen los límites superior e inferior.
limits <- aes(ymax = resp + se, ymin = resp - se)
En esa línea, le dices explícitamente a ggplot que ponga la extensión inferior configurando ymin como resp - se
; si lo configuras como resp
, entonces solo tendrías la extensión superior.
limits <- aes(ymax = resp + se, ymin = resp)
... aunque también tendrías una línea negra en la parte superior de la barra. Para que este se vea más limpio, puede agregar un contorno negro a toda la barra.
p <- ggplot(df, aes(fill = group, y = resp, x = trt))+
geom_bar(position = dodge, stat = "identity") +
geom_bar(position = dodge, stat = "identity",
color="black", show_guide=FALSE)+
geom_errorbar(limits, position = dodge, width = 0.25)
p
Observe cómo dupliqué la capa de gráfico de barras, pero con un color "negro", que agrega ese contorno. La leyenda se desactivó en la capa de color porque personalmente prefiero evitar las líneas diagonales en la leyenda.
En realidad, es bastante fácil implementar esto para su uso en el caso general (donde no puede ocultar la barra de error inferior debajo de otro elemento de la trama) ahora que han facilitado la extensión ggplot2
con costumbre geom
s.
Copia el código de geom_errorbar
desde el repositorio de github para ggplot2
en un nuevo archivo .R. Luego haga algunas modificaciones, como sigue:
geom_uperrorbar <- function(mapping = NULL, data = NULL,
stat = "identity", position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE)
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomUperrorbar,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
...
)
)
Los únicos dos cambios necesarios arriba fueron cambiar geom_errorbar
a geom_uperrorbar
y geom = GeomErrorbar
a geom = GeomUperrorbar
.
GeomUperrorbar <- ggproto("GeomUperrorbar", Geom,
default_aes = aes(colour = "black", size = 0.5, linetype = 1, width = 0.5,
alpha = NA),
draw_key = draw_key_path,
Tenga en cuenta que este comentario se interrumpe a la mitad de una función que continúa en los bloques de código a continuación. Arriba acabamos de cambiar GeomErrorbar
a GeomUperrorbar
dos veces.
required_aes = c("x", "y", "ymax"),
setup_data = function(data, params) ,
Interrumpiendo la función nuevamente. Arriba cambiamos la estética requerida para ser x
, y
y ymax
, es decir, reemplazando ymin
con y
. Nosotros necesitamos y
para comenzar la línea vertical allí (en lugar de en ymin
) y ya no necesitamos ymin
porque no va a haber una línea horizontal allí.
draw_panel = function(data, panel_scales, coord, width = NULL)
GeomPath$draw_panel(data.frame(
x = as.vector(rbind(data$xmin, data$xmax, NA, data$x, data$x)),
y = as.vector(rbind(data$ymax, data$ymax, NA, data$ymax, data$y)),
colour = rep(data$colour, each = 5),
alpha = rep(data$alpha, each = 5),
size = rep(data$size, each = 5),
linetype = rep(data$linetype, each = 5),
group = rep(1:(nrow(data)), each = 5),
stringsAsFactors = FALSE,
row.names = 1:(nrow(data) * 5)
), panel_scales, coord)
)
Aquí eliminamos los últimos tres elementos de los vectores pasados a x
y y
, que eran para la barra de error inferior. Además, cambiamos el último elemento de ymin
a y
, porque queremos que la línea comience en y
, no ymin
.
"%||%" <- function(a, b)
if (!is.null(a)) a else b
Este último bit es solo una función de conveniencia utilizada en el código que debe definirse.
Si obtiene el documento que incluye todo este código, puede usar geom_uperrorbar
al igual que geom_errorbar
, o incluso pasar geom = "uperrorbar"
a stat_summary
, utilizando y
en vez de ymin
.
Si eres capaz, eres capaz de dejar un escrito acerca de qué le añadirías a esta reseña.