Сохранить участок в объекте

83

В ggplot2, можно легко сохранить графику в объект R.

p = ggplot(...) + geom_point()      # does not display the graph
p                                   # displays the graph

Стандартная функция plotсоздает графику как функцию void и возвращает NULL.

p = plot(1:10)     # displays the graph
p                  # NULL

Можно ли сохранить графику, созданную plotв объекте?

Remi.b
источник
plotявляется универсальным, и, plotнасколько мне известно , разные методы возвращают такие объекты. plot.defaultОднако действительно возвращается NULL.
Конрад Рудольф
Ваша цель - иметь возможность воспроизвести график только путем ввода pпосле сохранения его как объекта? Или вы хотите сохранить его как объект, для которого вы сможете, например, изменить его значения?
LyzandeR
Я мог бы захотеть наложить другую графику поверх сохраненной графики, но я не собираюсь изменять созданный и сохраненный сюжет. Я ответил на твой вопрос? Thks
Remi.b
@ Remi.b Спасибо. Я опубликовал решение, которое может помочь.
LyzandeR

Ответы:

95

базовая графика рисуется прямо на устройстве.

Вы могли бы использовать

1- recordPlot

2- недавно представленный gridGraphicsпакет для преобразования базовой графики в их эквивалент сетки

Вот минимальный пример,

plot(1:10) 

p <- recordPlot()
plot.new() ## clean up device
p # redraw

## grab the scene as a grid object
library(gridGraphics)
library(grid)
grid.echo()
a <- grid.grab()

## draw it, changes optional
grid.newpage()
a <- editGrob(a, vp=viewport(width=unit(2,"in")), gp=gpar(fontsize=10))
grid.draw(a)
батист
источник
1
Мне неясно: являются ли (1) и (2) отдельными методами для достижения одной и той же цели или два шага, необходимые для ответа на вопрос OP?
NLi10Me
@ NLi10Me 2 разных метода.
zx8754
Если я попытаюсь saveRDS(object = p, file = "p.Rds")загрузить новый сеанс R, запустите, p <- readRDS(file = "p.Rds")а затем pя получаю сообщение об ошибке Error in replayPlot(x) : loading snapshot from a different session. Я pнеправильно сохраняю объект?
user5359531
Кажется, что ошибка, которую я получал, была решена в R 3.3.0 , используя эту версию, она работает. Когда я использовал gridGraphicsметод, показанный здесь, цвета на перерисованном графике продолжали grid.grab(wrap=TRUE)
путаться
34

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

Я решил это, используя функцию вместо объекта. Например, предположим, что мы хотим сравнить два бета-распределения с разными параметрами. Мы можем запустить:

z1<-rbeta(10000,5,5)
z2<-rbeta(10000,20,20)
plotit<-function(vector,alpha,beta){
plot(density(vector),xlim=c(0,1))
abline(v=alpha/(alpha+beta),lty="longdash")
}

И сохраняйте графики как функции, а не как объекты.

z.plot1<-function(){plotit(z1,5,5)}
z.plot2<-function(){plotit(z2,20,20)}

Затем мы можем вызывать каждый график по своему усмотрению, просто вызывая два графика как функции, а не как объекты.

z.plot1()

строит первый сюжет и

z.plot2()

сюжеты второй.

Надеюсь, это поможет тому, кто столкнется с этим позже!

колесо телеги
источник
Это очень полезно! Я думаю, что это отличная идея для подготовки предустановленных сюжетов, это то, что я искал
Jojostack
Это гениальный подход на основе R! recordPlotопределенно полезен (если у вас уже открыто окно), но это именно то, что люди ищут, когда посещают этот пост. +1!
theforestecologist
Особенно полезно для сложных составных сюжетов.
Джо
Разрешите присоединиться к хору людей, которые действительно ценят этот трюк. Также от имени моих учеников :-)
Laryx Decidua
Лексическая область видимости снова приходит на помощь! :)
Джейсон
17

Вы можете использовать функцию активной привязки pryrпакета, если не хотите напрямую изменять значения созданного объекта.

library(pryr)
a %<a-% plot(1:10,1:10)

Каждый раз, когда вы вводите aтекст на консоли, график будет воспроизводиться на экране. %<a-%Оператор перезапуске скрипта каждый раз (в случае одного графа это не проблема , я думаю). Таким образом, практически каждый раз, когда вы используете aкод, он будет запускаться повторно, что приведет к вашему графику, которым вы, конечно же, можете манипулировать (наложить другой график сверху) или сохранить, pngнапример. Однако само значение не будет сохранено в a. Значение по-прежнему будет NULL.

Я не знаю, является ли вышеперечисленное то, что вы ищете, но это может быть приемлемым решением.

LyzandeR
источник
Спасибо. Это очень удобное решение. Вы знаете, работает ли это, если сюжет построен из нескольких линий (например, plot(1:10);abline(v=4)например)? +1
Remi.b
@ Remi.b Да, конечно. Однако вам нужно ввести его вот так " a %<a-% {plot(1:10);abline(v=4)}. Если вы введете его в фигурных скобках, у вас может быть столько строк, сколько захотите! Кроме того, если вы хотите переназначить значение, aвам нужно сначала удалить его, rm(a)а затем переназначить с помощью %<a-%оператор в противном случае вы получите предупреждение , я не знаю , почему это происходит , но я предполагаю , что это не имеет большого значения ..
LyzandeR
Это действительно круто! Мне придется немного прочитать об этом пакете, потому что мне кажется невозможным делать то, что делает эта странная функция %<a-%. Спасибо
Remi.b
Да, это еще одна из тех действительно крутых упаковок, которые сделал Хэдли. Это набор функций, позволяющих глубоко понять язык R. Также посмотрите %<d-%, это может пригодиться позже. Рад, что смог помочь :)
LyzandeR
1
@LyzandeR можно ли объединить сохраненные участки в мультиплот?
user2300940
-4
library(ggplot2)
# if mygraph is a plot object
ggsave("myplot1.png",mygraph)

# if the plot is in a list (e.g. created by the Bibliometrics package)
ggsave("myplot1.png",mygraphs[[1]])
Доктор Т.
источник
Хотя ваш ответ выглядит «правильным» (но я не программист на R), в Stack Overflow обычной практикой является добавление пояснительного текста, а не просто публикация «краткого» блока, состоящего только из кода. Это делает ответ более ценным в долгосрочной перспективе и для более широкого круга пользователей. (Но все равно оставьте свой голос за!)
Адриан Моул
3
OP спрашивал, как это сделать без использования ggplot2.
Джейсон