Speichern Sie ein Diagramm in einem Objekt

83

In ggplot2kann man eine Grafik einfach in einem R-Objekt speichern.

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

Die Standardfunktion ploterzeugt die Grafik als ungültige Funktion und gibt NULL zurück.

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

Ist es möglich, eine von plotin einem Objekt erstellte Grafik zu speichern ?

Remi.b
quelle
plotist eine generische und verschiedene plotMethoden geben solche Objekte zurück, soweit ich weiß. plot.defaultkehrt jedoch tatsächlich zurück NULL.
Konrad Rudolph
Ist es Ihr Ziel, Ihr Diagramm nur durch Eingabe pnach dem Speichern als Objekt neu zu zeichnen ? Oder möchten Sie es als Objekt speichern, das Sie dann beispielsweise ändern können?
LyzandeR
Möglicherweise möchte ich andere Grafiken über die gespeicherte Grafik legen, aber ich möchte das erstellte und gespeicherte Diagramm nicht ändern. Habe ich deine Frage beantwortet? Thks
Remi.b
@ Remi.b Es tut danke. Ich habe eine Lösung veröffentlicht, die helfen könnte.
LyzandeR

Antworten:

95

Basisgrafiken werden direkt auf einem Gerät gezeichnet.

Du könntest benutzen

1- recordPlot

2- das kürzlich eingeführte gridGraphicsPaket , um Basisgrafiken in ihre Rasteräquivalente zu konvertieren

Hier ist ein minimales Beispiel:

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)
Baptiste
quelle
1
Mir ist unklar: Sind (1) und (2) getrennte Methoden, um dasselbe Ziel zu erreichen, oder sind zwei Schritte erforderlich, um die Frage des OP zu beantworten?
NLi10Me
@ NLi10Me 2 verschiedene Methoden.
zx8754
Wenn ich es versuche saveRDS(object = p, file = "p.Rds"), lade ich eine neue R-Sitzung, führe sie aus, p <- readRDS(file = "p.Rds")gefolgt von peiner Fehlermeldung Error in replayPlot(x) : loading snapshot from a different session. Speichere ich das pObjekt falsch?
user5359531
Es scheint, dass der Fehler, den ich bekam, in R 3.3.0 behoben wurde , mit dieser Version, die es funktioniert. Als ich die gridGraphicshier gezeigte Methode verwendete, wurden die Farben auf dem neu gezeichneten Plot immer wieder durcheinander gebracht, selbst mitgrid.grab(wrap=TRUE)
user5359531
34

Ich bin sehr spät dran, aber es war die erste Frage, die auftauchte, als ich nach der Frage suchte. Daher möchte ich meine Lösung für zukünftige Zuschauer hinzufügen, die auf die Frage stoßen.

Ich habe dies gelöst, indem ich eine Funktion anstelle eines Objekts verwendet habe. Angenommen, wir möchten zwei Beta-Verteilungen mit unterschiedlichen Parametern vergleichen. Wir können rennen:

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")
}

Und speichern Sie die Diagramme als Funktionen und nicht als Objekte.

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

Als nächstes können wir jedes Diagramm wie gewünscht aufrufen, indem wir einfach die beiden Diagramme als Funktionen und nicht als Objekte aufrufen.

z.plot1()

zeichnet die erste Handlung und

z.plot2()

zeichnet die zweite.

Hoffe das hilft jemandem, der später darüber stolpert!

Wagenrad
quelle
Das ist sehr nützlich! Ich denke, es ist eine großartige Idee, um voreingestellte Diagramme vorzubereiten. Dies ist, wonach ich gesucht habe
Jojostack
Dies ist ein genialer Basis-R-Ansatz! recordPlotist definitiv nützlich (wenn Sie ein Fenster bereits geöffnet haben), aber diese Antwort ist genau das, wonach Leute suchen, wenn sie diesen Beitrag besuchen. +1!
Theforestecologist
Besonders nützlich für komplexe Mehrfachdarstellungen.
Joe
Lassen Sie mich dem Chor der Leute beitreten, die diesen Trick wirklich schätzen. Auch im Namen meiner Schüler :-)
Laryx Decidua
Lexikalisches Scoping zur Rettung! :)
Jason
17

Sie können die aktive Bindungsfunktion des pryrPakets verwenden, wenn Sie die Werte des erstellten Objekts nicht direkt ändern möchten.

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

Jedes Mal, wenn Sie aauf der Konsole eingeben, wird das Diagramm auf dem Bildschirm neu gedruckt. Der %<a-%Operator führt das Skript jedes Mal erneut aus (im Fall eines Diagramms ist dies meines Erachtens kein Problem). Im Wesentlichen wird also jedes Mal, wenn Sie aden Code verwenden, erneut ausgeführt, was zu Ihrem Diagramm führt, das Sie natürlich bearbeiten (ein anderes Diagramm darüber legen) oder beispielsweise mit speichern können png. Es wird jedoch kein Wert selbst gespeichert a. Der Wert bleibt weiterhin NULL.

Ich weiß nicht, ob das, was Sie suchen, das ist, aber es könnte eine akzeptable Lösung sein.

LyzandeR
quelle
Vielen Dank. Das ist eine sehr praktische Lösung. Wissen Sie, ob dies funktioniert, wenn das Diagramm aus mehreren Linien besteht (wie plot(1:10);abline(v=4)zum Beispiel)? +1
Remi.b
@ Remi.b Ja natürlich. Sie müssen es jedoch so eingeben " a %<a-% {plot(1:10);abline(v=4)}. Wenn Sie es in diese geschweiften Klammern eingeben, können Sie so viele Zeilen haben, wie Sie möchten! Wenn Sie einen Wert neu zuweisen möchten, amüssen Sie ihn zuerst mit entfernen rm(a)und dann mit neu zuweisen der %<a-%Betreiber sonst erhalten Sie eine Warnung. Ich weiß nicht, warum dies passiert, aber ich denke, es ist keine große Sache.
LyzandeR
Das ist wirklich cool! Ich muss ein wenig über dieses Paket lesen, weil es für mich unmöglich klingt, das zu tun, was diese seltsame Funktion %<a-%tut. Danke
Remi.b
Ja, es ist ein weiteres dieser wirklich coolen Pakete, die Hadley gemacht hat. Es handelt sich um eine Reihe von Funktionen, mit denen Sie die R-Sprache gründlich verstehen können. Schauen Sie sich auch an %<d-%, es könnte später nützlich sein. Ich bin froh, dass ich helfen konnte :)
LyzandeR
1
@LyzandeR ist es möglich, die gespeicherten Diagramme zu einem Multiplot zu kombinieren?
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]])
Dr. T.
quelle
Obwohl Ihre Antwort "richtig" aussieht (aber ich bin kein R-Programmierer), ist es bei Stack Overflow üblich, erklärenden Text hinzuzufügen, anstatt nur einen "knappen" Nur-Code-Block zu veröffentlichen. Dies macht die Antwort langfristig und für ein breiteres Anwenderspektrum wertvoller. (Aber haben Sie trotzdem eine Gegenstimme!)
Adrian Mole
3
Das OP fragte, wie dies ohne Verwendung von ggplot2 geschehen könne.
Jason