Зберегти сюжет в об’єкті


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в об'єкті?


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) окремі методи для досягнення однієї і тієї ж мети, або обидва кроки необхідні для відповіді на питання ОП?
NLi10,

@ 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!
форестеколог,

Особливо корисно для складних декількох ділянок.
Джо

Дозвольте мені приєднатися до хору людей, які справді цінують цей фокус. Також від імені моїх студентів :-)
Laryx Decidua

Лексичний обсяг на допомогу знову! :)
Джейсон,

17

Ви можете використовувати функцію активного прив’язки pryrпакета, якщо не хочете безпосередньо змінювати значення створеного об’єкта.

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

Щоразу, коли ви вводите текст aна консолі, графік буде передруковуватися на екрані. %<a-%Оператор перезапуску скрипта щораз (у разі одного графа це не проблема , я думаю). Таким чином, по суті, кожного разу, коли ви використовуєте aкод, буде перезапущено, що призведе до вашої графіки, яку, звичайно, ви можете маніпулювати (накласти інший графік зверху) або зберегти, використовуючи, pngнаприклад. aОднак жодне значення не буде збережене . Значення все одно буде NULL.

Я не знаю, чи вище ви шукаєте, але це може бути прийнятним рішенням.


Дякую. Це дуже зручне рішення. Чи знаєте ви, чи це працює, якщо сюжет будується через кілька рядків (наприклад, plot(1:10);abline(v=4)наприклад)? +1
Remi.b

@ Remi.b Так, звичайно. Вам потрібно ввести його так, хоча " a %<a-% {plot(1:10);abline(v=4)}. Якщо ви введете його всередину цих фігурних дужок, ви можете мати скільки завгодно рядків! Крім того, якщо ви хочете перепризначити значення, aвам потрібно спочатку видалити його, rm(a)а потім перепризначити за допомогою в %<a-%іншому випадку ви отримуєте попередження. Я не знаю, чому це трапляється, але, мабуть, це не велика
проблема

Це справді круто! Мені доведеться трохи прочитати про цей пакет, тому що мені здається неможливим робити те, що робить ця дивна функція %<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
ОП запитував про те, як це зробити без використання ggplot2.
Джейсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.