Подтвердить что ты не робот

Удалить геометрию из существующей диаграммы ggplot?

Я пытаюсь понять, как я могу вносить изменения в внутренности диаграммы ggplot2. Я начал читать несколько ресурсов, которые я мог найти о ggplot_built и ggplot_gtable, но я не мог ответить на вопрос ниже.

С учетом графика g с 2 geom.

g <- ggplot(iris, aes(Petal.Length, Petal.Width)) + 
  geom_point() + 
  geom_text(aes(label=Sepal.Width))
g

enter image description here

Есть ли способ погрузиться в объект g и удалить одну или несколько геометров?

Могу ли я получить, начиная с g, сюжет без геом?

enter image description here

Или с geom_text?

enter image description here


ОБНОВЛЕНИЕ после более тщательного тестирования ответов

Я только заметил, что удаление геометров может повлиять на расположение других геометрий. Вероятно, большой по умолчанию и предполагаемое поведение для большинства случаев использования, но мне действительно нужна точная схема "макета" (ось и положение оставшихся геометрий).

Например, перед удалением одной геометрии:

library(dplyr)
library(ggplot2)
count(mpg, class) %>%
  mutate(pct=n/sum(n)) %>%
  ggplot(aes(class, pct)) +
  geom_col(fill="blue") +
  geom_line(group=1) +
  geom_point(size=4) 

enter image description here

после удаления одной геометрии (обратите внимание, что ось y больше не начинается с 0, я думаю, что поведение по умолчанию для строки/точки без баров):

library(dplyr)
library(ggplot2)
count(mpg, class) %>%
  mutate(pct=n/sum(n)) %>%
  ggplot(aes(class, pct)) +
  geom_col(fill="blue") +
  geom_line(group=1) +
  geom_point(size=4) -> p
p$layers[[1]] <- NULL
p

enter image description here

Любые способы заставить ggplot сохранить тот же самый макет?

4b9b3361

Ответ 1

Вы можете получить доступ к элементам g или манипулировать ими так же, как с другим объектом R

g$layers
#[[1]]
#geom_point: na.rm = FALSE
#stat_identity: na.rm = FALSE
#position_identity 

#[[2]]
#mapping: label = Sepal.Width 
#geom_text: parse = FALSE, check_overlap = FALSE, na.rm = FALSE
#stat_identity: na.rm = FALSE
#position_identity 

Удалить geom_text:

g$layers[[2]] <- NULL

Удалить все layers

g$layers <- NULL
g

enter image description here


Пакет gginnards предлагает некоторые функции для управления слоями ggplot, подробности см. В Руководстве пользователя виньетки : 4 Управление слоями ggplot.


редактировать

После вопроса Как я могу извлечь диапазоны осей графика для объекта ggplot2? Я пришел к решению, которое использует ggplot_build и ggplot_gtable. Идея состоит в том, чтобы просто скопировать параметры макета, взятые из ggplot_built(p) в новый график, для которого мы удалили слой.

# create a copy of p
p_new <- p

# delete the first layer
p_new$layers[[1]] <- NULL
p_new_build <- ggplot_build(p_new)

# this is the important line
p_new_build$layout$panel_params <- ggplot_build(p)$layout$panel_params

library(gridExtra)
grid.arrange(p, ggplot_gtable(p_new_build), ncol = 2)

enter image description here

Ответ 2

Вы можете использовать пакет gginnards, чтобы сделать жизнь проще

library(ggplot2)

### sample plot w/ both points and labels
g <- ggplot(iris, aes(Petal.Length, Petal.Width)) + 
  geom_point() + 
  geom_text(aes(label = Sepal.Width))
g

### https://cran.rstudio.com/web/packages/gginnards/vignettes/user-guide-2.html
library(gginnards)

### remove points
delete_layers(g, "GeomPoint")

### remove text
delete_layers(g, "GeomText")

Ответ 3

Вы можете попробовать добавить альфа. Вместо удаления слоя он не появится.

count(mpg, class) %>%
  mutate(pct=n/sum(n)) %>%
  ggplot(aes(class, pct)) +
  geom_col(fill="blue", alpha=0) +
  geom_line(group=1) +
  geom_point(size=4)

enter image description here

Вы можете, конечно, добавить альфа впоследствии, как

p <- ggplot_build(p)
p$data[[1]]$alpha <- 0
plot(ggplot_gtable(p))

Ответ 4

Постройте график, чтобы весь материал waiver() (ограничения по оси и метки и т.д.) gtable это, а затем преобразовывал его в gtable для построения графика.

p_built <- ggplot_build(p)
p_built$plot$layers[[1]] <- NULL
p_built$data[[1]] <- NULL
plot(ggplot_gtable(p_built))

Обратите внимание, что вам нужно удалить не только слой, но и набор данных для этого слоя.