2015-01-22 9 views
6

facet_grid mi permettono di taglia ciascuna larghezza sfaccettatura base al numero di elementi sull'asse y (space argomento):'etichette sulla parte superiore' con facet_grid, o 'opzione spazio' con facet_wrap

df <- data.frame(label = c("Variable one", rep("Variable two", 2), rep("Variable three", 3)), item = c("A", "B", "C", "D", "E", "F"), value = rnorm(6)) 
ggplot(df, aes(x = value, y = item)) + 
geom_point() + 
facet_grid(label ~ ., scales = "free_y", space = "free_y") + 
ylab("") + 
theme(strip.text.y = element_text(angle=0)) 

enter image description here

Ma vorrei etichette sfaccettatura sulla parte superiore, in modo da passare a facet_wrap, e ha perso i space argomento (sfaccettature hanno tutti la stessa larghezza):

ggplot(df, aes(x = value, y = item)) + 
geom_point() + 
facet_wrap(~ label, scales = "free_y", ncol = 1) + 
ylab("") 

enter image description here

È possibile ottenere il meglio da entrambi i mondi?

Grazie in anticipo per il vostro aiuto.

risposta

3

può essere fatto manualmente. Il rapporto tra le altezze dei tre pannelli nella trama desiderata è approssimativamente 1: 3: 2. Le altezze dei tre pannelli possono essere registrati cambiando la grobs:

library(ggplot2) 
library(grid) 
df <- data.frame(label = c("Variable one", rep("Variable two", 2), rep("Variable three", 3)), item = c("A", "B", "C", "D", "E", "F"), value = rnorm(6)) 

p1 = ggplot(df, aes(x = value, y = item)) + 
geom_point() + 
facet_wrap(~ label, scales = "free_y", ncol = 1) + 
ylab("") 

g1 = ggplotGrob(p1) 

g1$heights[[7]] = unit(1, "null") 
g1$heights[[12]] = unit(3, "null") 
g1$heights[[17]] = unit(2, "null") 

grid.newpage() 
grid.draw(g1) 

Oppure, le altezze possono essere impostati per essere gli stessi di quelli nella trama originale:

p2 = ggplot(df, aes(x = value, y = item)) + 
geom_point() + 
facet_grid(label ~ ., scales = "free_y", space = "free_y") + 
ylab("") + 
theme(strip.text.y = element_text(angle=0)) 

g2 = ggplotGrob(p2) 

g1$heights[[7]] = g2$heights[[6]] 
g1$heights[[12]] = g2$heights[[8]] 
g1$heights[[17]] = g2$heights[[10]] 

grid.newpage() 
grid.draw(g1) 

Or, le altezze può essere impostato senza riferimento alla trama originale. Possono essere impostati in base al numero di items per ogni label in df. E prendendo in prestito qualche codice da @baptiste's answer here per selezionare le voci dal layout corrispondente ai pannelli:

# From 'df', get the number of 'items' for each 'label'. 
# That is, the number y-breaks in each panel. 
library(plyr) 
N = dlply(df, .(label), function(x) length(row.names(x))) 

# Get the items in the g1 layout corresponding to the panels. 
panels1 <- g1$layout$t[grepl("panel", g1$layout$name)] 

# Replace the default panel heights with relative heights 
g1$heights[panels1] <- unit(N, "null") 

## Draw g1 
grid.newpage() 
grid.draw(g1) 

enter image description here

4

non so come farlo in ggplot, ma si può ottenere un layout simile con uno stile OID ggplot utilizzando latticeExtra:

library(latticeExtra) 
df$label <- factor(df$label, levels = unique(df$label)) 

dotplot(item ~ value | label, data = df, 
     layout = c(1, 3), 
     as.table = TRUE, 
     scales = list(y = list(relation = "free")), 
     par.settings = ggplot2like()) 
resizePanels() 

enter image description here

Problemi correlati