2015-03-15 4 views
9

Я размещаю несколько графиков в одном изображении с помощью gridExtra::grid.arrange и хотел бы иметь возможность сохранять комбинированный график как объект, который может быть возвращен из функции как часть списка возвращаемых объектов. В идеале я хотел бы сделать это без печати объекта сюжета.Сохранить вывод из gridExtra :: grid.arrange в объект

Код ниже создает два графика, объединяет их с grid.arrange и пытается сохранить результат в x. Однако x оценивает NULL и график распечатывается. Документация для grid.arrange указывает мне на arrangeGrob и предлагает, чтобы график можно отключить с помощью plot=FALSE, но я получаю сообщение об ошибке, когда я пытаюсь это сделать, потому что FALSE не является объектом grob.

Любые предложения по поводу того, что я не понимаю?

# R under development 
# Windows 7 (32 bit) 
# ggplot2 1.0.0 
# gridExtra 0.9.1 

p1 <- ggplot(mtcars, aes(x=factor(cyl), y=mpg)) + geom_boxplot() 

p2 <- ggplot(mtcars, aes(x=factor(cyl), y=wt)) + geom_boxplot() 

x <- gridExtra::grid.arrange(p1, p2) 

x 

В комментариях, я добавляю это изменение. Когда я пытаюсь сделать это с arrangeGrob, я не получаю никакого вывода.

> gridExtra::arrangeGrob(p1, p2) 
> print(gridExtra::arrangeGrob(p1, p2)) 
Error: No layers in plot 
> x <- gridExtra::arrangeGrob(p1, p2) 
> x 
Error: No layers in plot 
+5

Попробуйте использовать 'organizGrob' вместо – hrbrmstr

+1

@hrbrmstr: Я думаю, что небольшой ответ был бы полезен. Страница справки довольно бесполезна в этом случае, и это было не то, что я мог бы ответить на макушку, несмотря на хороший опыт. –

+0

На самом деле это становится более странным с 'organizGrob' (я все время забываю, что код не форматируется в комментариях, поэтому я сделал редактирование вопроса). – Benjamin

ответ

2

код в вашем редактирования не работает должным образом, так как вы не сработал gridExtra.

library(gridExtra) 
y <- arrangeGrob(p1, p2, ncol = 1) 
class(y) 
#[1] "gtable" "grob" "gDesc" 
grid.draw(y) 

enter image description here

Edit: начиная с версии 2.0.0, мой комментарий о grid зависимость ниже уже не действует, так как grid теперь импортируется.

Edit: С gridExtra версии> = 2.0.0, нет необходимости придавать либо пакет,

p <- ggplot2::qplot(1,1) 
x <- gridExtra::arrangeGrob(p, p) 
grid::grid.draw(x) 
+0

Интересно. Я не ожидал такого поведения. Возможно, я не понимаю оператора '::', как я думал. Спасибо, что поставил меня прямо. – Benjamin

+0

Извините, после загрузки 'gridExtra' вам не нужно' gridExtra :: ', см. Редактирование. Добро пожаловать! – tonytonov

+0

Что мне не нужно «gridExtra ::» после загрузки пакета, который я понял. Я использовал оператор '::', потому что у меня есть эта функция в пакете, и я стараюсь не загружать дополнительные пакеты в путь поиска при загрузке моего пакета. Я думал, что загрузка библиотеки или использование '::' приведет к идентичным результатам. По-видимому, это не так. – Benjamin

2

Забавно, что это был задан вопрос совсем недавно - я бегу в эту проблему, а на этой неделе и был в состоянии решить это немного взломанным способом, но я не мог найти другого решения, с которым я был более счастлив.

Задача 1: ggplotGrob не найден

Я должен был убедиться, что ggplot2 загружен. Я не совсем понимаю, что происходит (я признаю, что не совсем понимаю импорт/зависимость/присоединение/etc), но следующие исправления. Я был бы открыт для обратной связи, если это очень опасно.

if (!"package:ggplot2" %in% search()) { 
    suppressPackageStartupMessages(attachNamespace("ggplot2")) 
    on.exit(detach("package:ggplot2")) 
} 

Кто-то связан с this blog post, и я думаю, что работает хорошо, но из моего (не полного) понимания, это решение менее ужасно. Я думаю.

Задача 2: нет слоев в участке

Как вы обнаружили также, фиксируя эту проблему позволяет использовать grid.arrange, но возвращает NULL и не позволяет экономить на объект. Поэтому я также хотел использовать arrangeGrob, но я также столкнулся с вышеуказанной ошибкой, когда gridExtra еще не загружен. Повторное применение исправления от проблемы 1, похоже, не работает (возможно, пакет слишком рано отключается?). НО я заметил, что вызов grid::grid.draw на результат arrGrob печатает его без ошибок. Поэтому я добавил пользовательский класс к выходу arrGrob и добавил общий метод печати, который просто вызывает сетку.рисовать

f <- function() { 
    plot <- gridExtra::arrangeGrob(...) 
    class(plot) <- c("ggExtraPlot", class(plot)) 
    plot 
} 
print.ggExtraPlot <- function(x, ...) { 
    grid::grid.draw(x) 
} 

Hooray, теперь я могу открыть свежий R сессию без каких-либо пакетов явно загружены, и я могу успешно вызвать функцию, которая создает Grob и распечатать его позже!


Вы можете увидеть код в действии in my package on GitHub.