2012-09-24 8 views
12

Estoy tratando de crear una gráfica con facetas con coordenadas volteadas donde uno y solo uno de los ejes se permite que varíe para cada faceta:Usar coord_flip() con facet_wrap (scales = "free_y") en ggplot2 parece dar marcas de eje de facetas inesperadas y marcar etiquetas

require(ggplot2) 
p <- qplot(displ, hwy, data = mpg) 
p + facet_wrap(~ cyl, scales = "free_y") + coord_flip() 

enter image description here

Esta trama no es satisfactorio para mí porque las marcas de graduación equivocadas y marque las etiquetas se repiten para cada parcela. Quiero marcas en cada eje horizontal no en cada eje vertical.

Esto es un comportamiento inesperado porque la gráfica implica que las marcas de eje horizontales son las mismas para los paneles superiores que para las inferiores, pero no lo son. Para ver esta carrera:

p <- qplot(displ, hwy, data = mpg) 
p + facet_wrap(~ cyl, scales = "fixed") + coord_flip() 

Así que mi pregunta es: ¿hay una manera de eliminar las marcas de graduación del eje vertical para el facetas correctas y añadir marcas y etiquetas de garrapatas eje horizontal al principio facetas?

Como señala Paul acertadamente a continuación, el ejemplo que di se puede abordar intercambiando xey en qplot() y evitando coord_flip(), sin embargo, esto no funciona para todos los geoms, por ejemplo, si quiero una horizontal facetada diagrama de barras con ejes horizontales gratuitas que podría funcionar:

c <- ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar() 
c + facet_wrap(~cut, scales = "free_y") + coord_flip() 

image

Estas facetas tienen un eje horizontal variable, pero repetidas marcas de graduación del eje vertical en vez de ejes horizontales repetidas marcas de graduación. No creo que el truco de Paul funcione aquí, porque a diferencia de los diagramas de dispersión, los diagramas de barras no son rotacionalmente simétricos.

Estaría muy interesado en escuchar cualquier solución parcial o completa.

+0

Creo que su punto es válido. Puede enviar un correo electrónico a la lista de correo ggplot2 o crear un ticket en el rastreador de problemas ggupot2 github. –

+0

Hecho. https://github.com/hadley/ggplot2/issues/673 – orizon

+0

Manténganos informados sobre las actualizaciones –

Respuesta

6

Esta es la segunda o tercera vez que me he encontrado con este problema yo mismo. He descubierto que puedo hackear mi propia solución definiendo un geom personalizado.

geom_bar_horz <- function (mapping = NULL, data = NULL, stat = "bin", position = "stack", ...) { 
    GeomBar_horz$new(mapping = mapping, data = data, stat = stat, position = position, ...) 
} 

GeomBar_horz <- proto(ggplot2:::Geom, { 
    objname <- "bar_horz" 

    default_stat <- function(.) StatBin 
    default_pos <- function(.) PositionStack 
    default_aes <- function(.) aes(colour=NA, fill="grey20", size=0.5, linetype=1, weight = 1, alpha = NA) 

    required_aes <- c("y") 

    reparameterise <- function(., df, params) { 
    df$width <- df$width %||% 
     params$width %||% (resolution(df$x, FALSE) * 0.9) 
    OUT <- transform(df, 
       xmin = pmin(x, 0), xmax = pmax(x, 0), 
       ymin = y - .45, ymax = y + .45, width = NULL 
    ) 
    return(OUT) 
    } 

    draw_groups <- function(., data, scales, coordinates, ...) { 
    GeomRect$draw_groups(data, scales, coordinates, ...) 
    } 
    guide_geom <- function(.) "polygon" 
}) 

Esta es sólo copiar el código geom_bar de la github ggplot2 y luego cambiar el x y y referencias para hacer una barplot horizontal en los coordinadores cartesianas estándar.

Tenga en cuenta que debe utilizar position='identity' y posiblemente también stat='identity' para que esto funcione. Si necesita utilizar una posición que no sea la identidad, deberá eddit el collide function para que funcione correctamente.

8

El uso de coord_flip junto con facet_wrap es el problema. Primero define un cierto eje para que sea libre (el eje x) y luego intercambia el eje, haciendo que el eje y sea libre. En este momento, esto no se reproduce bien en ggplot2.

En el primer ejemplo, yo recomendaría no usar coord_flip, pero simplemente intercambiando las variables en torno a su llamada a qplot, y el uso de free_x:

p <- qplot(hwy, displ, data = mpg) 
p + facet_wrap(~ cyl, scales = "free_x") 

enter image description here

+1

Ok, me sale su pregunta ahora. Evitaría usar 'facet_wrap' y' coord_flip' juntos. Simplemente invierta sus variables en la llamada a 'qplot'. Ver mi respuesta actualizada. –

+1

Esto funciona bien para los gráficos de puntos pero no para el histograma. Actualmente estoy teniendo el mismo problema con los gráficos de barras que quiero que sean horizontales y no puedo encontrar un camino. –

2

He estado tratando de hacer una barra horizontal, y me he encontrado con este problema donde quería scales = "free_x". Al final, parecía más fácil crear la barra de barras convencional (vertical), rota el texto para que, si inclinas la cabeza hacia la izquierda, se vea como la trama que deseas. Y luego, una vez que se termina su trama, girar la salida PDF/imagen (!)

ggplot(data, aes(x, y)) + 
    geom_bar(stat = "identity") + 
    facet_grid(var ~ group, scale = "free", space = "free_x", switch = "both") + 
    theme(axis.text.y = element_text(angle=90), axis.text.x = element_text(angle = 90), 
        strip.text.x = element_text(angle = 180)) 

Las principales claves para hacer esto son a switch = "both", que mueve las etiquetas de faceta al otro eje, y el element_text(angle=90) que gira las etiquetas del eje y el texto.

Cuestiones relacionadas