2016-11-25 7 views
3

Я хотел бы выборочно удалять ненужные грани из граненной фигуры ggplot2. Я имел взгляд на этот вопрос, но не мог понять, как это сделать (может быть, посоветуете там устарели):ggplot2: Удаление граней неиспользуемых комбинаций факторов уровня из графика (facet_grid)

adding empty graphs to facet_wrap in ggplot2

Вот минимальный пример. Я хотел бы удалить пустую грань в правом нижнем углу (b, 2).

library('ggplot2') 
d <- data.frame('factor_1' = factor(c('a', 'a', 'b')), 
       'factor_2' = factor(c('1', '2', '1')), 
       x = 1:3, y = 1:3) 

ggplot(data = d, mapping = aes(x = x, y = y)) + 
    geom_point() + 
    facet_grid(facets = factor_1 ~ factor_2, drop = TRUE) 

enter image description here

Очевидно drop = TRUE не имеет никакого эффекта, потому что здесь нет неиспользуемых уровней факторов, но их только неиспользуемые комбинации.

ответ

1

В ggplot2 2.2.0, имена grobs в сюжете есть изменилось.

library(ggplot2) 
library(grid) 
d <- data.frame('factor_1' = factor(c('a', 'a', 'b')), 
       'factor_2' = factor(c('1', '2', '1')), 
       x = 1:3, y = 1:3) 

p = ggplot(data = d, mapping = aes(x = x, y = y)) + 
    geom_point() + 
    facet_grid(facets = factor_1 ~ factor_2, drop = TRUE) 

# Get ggplot grob 
g = ggplotGrob(p) 

# Get the layout dataframe. 
# Note the names. 
# You want to remove "panel-2-2" 
g$layout 

# gtable::gtable_show_layout(g) # Might also be useful 

# Remove the grobs 
# The grob needs to be remove, 
# and the relevant row in the layout data frame needs to be removed 
pos <- grepl(pattern = "panel-2-2", g$layout$name) 
g$grobs <- g$grobs[!pos] 
g$layout <- g$layout[!pos, ] 


# Alternatively, replace the grobs with the nullGrob 
g = ggplotGrob(p) 
pos <- grep(pattern = "panel-2-2", g$layout$name) 
g$grobs[[pos]] <- nullGrob() 

# If you want, move the axis 
# g$layout[g$layout$name == "axis-b-2", c("t", "b")] = c(8, 8) 

# Draw the plot 
grid.newpage() 
grid.draw(g) 

enter image description here

Ответ в вашей ссылке будет необходимо модифицировать что-то вроде этого:

n <- 1000 
df <- data.frame(x = runif(n), y=rnorm(n), label = sample(letters[1:7], 
       size = n, replace = TRUE), stringsAsFactors=TRUE) 
df$label.new <- factor(df$label, levels=sort(c(""," ",levels(df$label)))) 


p <- ggplot(df, aes(x=x, y=y)) + geom_point() + 
     facet_wrap(~ label.new, ncol=3,drop=FALSE) 

g = ggplotGrob(p) 

g$layout # Note the names and their positions (t, b, l, r) 
# gtable::gtable_show_layout(g) # Might also be useful 

pos <- g$layout$name %in% c("panel-1-1", "panel-1-2", "strip-t-1-1", "strip-t-2-1") 
g$grobs <- g$grobs[!pos] 
g$layout <- g$layout[!pos, ] 

# Or replace the grobs with the nullGrob 
g = ggplotGrob(p) 
pos <- g$layout$name %in% c("panel-1-1", "panel-1-2", "strip-t-1-1", "strip-t-2-1") 
g$grobs[pos] <- list(nullGrob()) 

# Move the axis 
g$layout[g$layout$name == "axis-l-1-1", c("l", "r")] = c(10,10) 

grid.newpage() 
grid.draw(g) 
+0

Это отличный ответ и очень помогает мне. Однако, применяя его к моей проблеме, не связанной с игрушкой, я заметил, что (i) присвоение имен панелей (например, «панель-5-3» и т. Д.), Похоже, не относится к координатам панелей на графике, но по крайней мере они являются столбцами, упорядоченными в 'panel $ layout' и (ii) при настройке положений осей/полос (где именование прост), я не совсем понимаю, что позиционная информация (t (op), b (ottom), r (ight), l (eft)) в 'panel $ layout' фактически подразумевает. Не могли бы вы объяснить это или указать мне на какой-то полезный ресурс? Во всяком случае, спасибо A LOT. – NoBackingDown

+0

(i) t (op), b (ottom), r (ight), l (eft) дают степень grob относительно базового элемента gtable - см. Рамку данных компоновки. Вы также получаете изображение базового файла gtable, используя 'gtable_show_layout()'. Цифры в именах гномов, заданные в столбце «names» в кадре данных компоновки, не относятся к t, l, b, r. В версии 2.2.0 панель «5-3» будет означать «5 панелей вниз, 3 панели в поперечнике». Для полос первая цифра поперечная, вторая цифра вниз. Используйте 'gtable_show_layout()' и/или фрейм данных компоновки, чтобы совместить grobs с grobs name to tlbr. –

+0

(ii) В 'gtable_show_layout()' обратите внимание на строку (t и b) панели, к которой вы хотите привязать ось. В вашем примере это строка 7. Ось помещается на одну строку ниже, т. Е. На строку 8. Следовательно, t и b равны 8. Число столбцов (r и l) остается неизменным. Надеюсь это поможет. –

1

Не самое лучшее решение, но оно дает несколько удовлетворительный результат:

d$fInter <- interaction(d$factor_2, d$factor_1, sep = ' V ') 

    ggplot(data = d, mapping = aes(x = x, y = y)) + 
     geom_point() + 
     facet_wrap(~ fInter, drop = TRUE, 
       ncol = nlevels(d$factor_1)) 

И сюжет:

Plot

+0

Я боюсь, что обязательно нужно использовать 'facet_grid' и не' facet_wrap'. – NoBackingDown

+0

Могу ли я спросить, есть ли какие-то конкретные причины? Вместо нового значения взаимодействия вы можете использовать только ~ factor_1 + factor_2, но он будет менее приятным для глаз. –

+0

Это лишь минимальный пример, на самом деле у меня уже есть вложенные факторы для столбцов. – NoBackingDown