Jak zapisać działkę jako obraz na dysku?

304

Rysuję prostą regresję liniową za pomocą R. Chciałbym zapisać ten obraz jako PNG lub JPEG, czy można to zrobić automatycznie? (przez kod)

Istnieją dwa różne pytania: Po pierwsze, już patrzę na fabułę na monitorze i chciałbym ją zapisać bez zmian. Po drugie, nie wygenerowałem jeszcze wykresu, ale chciałbym zapisać go bezpośrednio na dysku podczas wykonywania mojego kodu wydruku.

blakc05
źródło
Być może to pytanie powinno zostać zredagowane, aby zadać dwa różne scenariusze: Po pierwsze, możesz pracować interaktywnie i stworzyć fajną fabułę, którą chcesz zapisać. Po drugie, nie widziałeś jeszcze żadnej fabuły i chcesz zapisać ją bezpośrednio na dysk, nie patrząc na nią wcześniej - miałoby to sens, gdybyś pisał skrypt generujący wiele fabuł dla Ciebie. Będę go teraz edytować
Aaron McDaid

Odpowiedzi:

376

Istnieją dwa ściśle powiązane pytania i odpowiedź na każde z nich.


1. W przyszłości w moim skrypcie zostanie wygenerowany obraz. Jak zapisać go na dysku?

Aby zapisać działkę, musisz wykonać następujące czynności:

  1. Otwórz urządzenie, za pomocą png(), bmp(), pdf()lub podobny
  2. Wykreśl swój model
  3. Zamknij urządzenie za pomocą dev.off()

Przykładowy kod do zapisania wykresu do pngpliku:

fit <- lm(some ~ model)

png(filename="your/file/location/name.png")
plot(fit)
dev.off()

Jest to opisane w (kombinowanego) stronie pomocy graficznych formatów ?png, ?bmp, ?jpegi ?tiff, jak również w oddzielnej stronie pomocy ?pdf.

Należy jednak pamiętać, że obraz na dysku może wyglądać inaczej niż ta sama fabuła narysowana bezpośrednio na ekranie, na przykład po zmianie rozmiaru okna ekranowego.


Pamiętaj, że jeśli twoja fabuła została stworzona przez jednego z nich latticelub ggplot2musisz jawnie wydrukować fabułę. Zobacz tę odpowiedź, która wyjaśnia to bardziej szczegółowo, a także linki do R FAQ: qplot ggplota nie wykonuje się podczas pozyskiwania


2. Obecnie patrzę na fabułę na ekranie i chcę skopiować ją „jak jest” na dysk.

dev.print(pdf, 'filename.pdf')

Powinno to idealnie skopiować obraz, z uwzględnieniem wszelkich zmian rozmiaru dokonanych w interaktywnym oknie. Możesz, podobnie jak w pierwszej części tej odpowiedzi, zastąpić pdfinnymi typami plików, takimi jak png.

Andrie
źródło
4
jeśli nie ustawisz ścieżki, np. png (nazwa_pliku = „nazwa.png”), możesz znać katalog zapisywania za pomocągetwd()
JuanPablo
2
Rozszerzyłem tę odpowiedź, aby zawierała odniesienie do dev.print. Są dwa ściśle powiązane pytania, które moim zdaniem wymagają różnych odpowiedzi. Drugie podpytanie to w zasadzie „Jak zapisać obraz, który już narysowałem na ekranie?”. Przepraszam, jeśli moja edycja nie jest zbyt dobra, możesz poprawić swoje zmiany.
Aaron McDaid
Jak to zrobić, gdy R poprosi o „Wybór”? Na przykład jeśli używam m3=garchFit(~arma(3,0)+garch(1,1))i plot(m3).
jacob
3
Jak zapisać liczbę z dpi = 3000
Abhishek,
2
8 lat korzystania z R, nie wiedząc, że mogę zapisać programistę otwartą na moim ekranie w pliku. Chyba nie potrzebowałem tego ... ale wielkie dzięki: D
Simon C.
82

Jeśli chcesz nadal widzieć wykres w R, inną opcją jest użycie dev.copy:

X11 ()
plot (x,y)

dev.copy(jpeg,filename="plot.jpg");
dev.off ();

Jeśli dojdziesz do zagracenia zbyt wielu okien wykresu w R, użyj, graphics.off()aby zamknąć wszystkie okna wykresu.

Itamar
źródło
2
Świetna odpowiedź! Dzięki temu możesz eksperymentować z wykresami za pomocą X, dopóki nie będziesz zadowolony z wyników, a następnie zapisz je na miejscu. Jest to zwykle najwygodniejszy tryb działania.
Aaron McDaid,
3
dev.printjest lepszy, ponieważ dokładnie kopiuje obraz z ekranu. dev.copywymusza domyślnie kwadratowy obraz. Jest to frustrujące, jeśli wszystko skonfigurujesz ładnie interaktywnie
Aaron McDaid
4
Używam dev.print()parametrów szerokości i wysokości do definiowania wymiarów. np. dev.copy(device = png, filename = 'MyPlot.png', width = 1000, height = 500) dev.off()
Scott
72

Jeśli korzystasz ggplot2z preferowanego sposobu oszczędzania, należy użyć ggsave. Najpierw musisz spiskować, po utworzeniu fabuły wywołujesz ggsave:

ggplot(...)
ggsave("plot.png")

Format obrazu zależy od rozszerzenia wybranego dla nazwy pliku. Dodatkowe parametry mogą być przekazywane ggsave, zwłaszcza width, heighti dpi.

Paul Hiemstra
źródło
To działa dobrze w pętli, dev.off nie działa dla mnie
princelySid
zaletą tego jest spójny interfejs API i nie ma potrzeby bałagania się przy włączaniu i wyłączaniu urządzeń
qwr
W przeciwieństwie do rozwiązań z dev, to rozwiązanie działało na maszynie wirtualnej bez urządzeń graficznych.
miguelmorin
Żałuję, że nie było takiego potężnego, ale prostego podejścia dla WSZYSTKICH działek w R. W każdym razie mój głos tu jest.
SilSur
1
Nadal obowiązuje prawie 7 lat! Dziękuję Ci.
Nick
30

Lubię to

png('filename.png')
# make plot
dev.off()

albo to

# sometimes plots do better in vector graphics
svg('filename.svg')
# make plot
dev.off()

albo to

pdf('filename.pdf')
# make plot
dev.off()

I prawdopodobnie także inni. Wszystkie są wymienione razem na stronach pomocy.

piekarnik
źródło
Czy istnieje sposób, by R mógł automatycznie wnioskować o rozszerzenie pliku (tj. Na podstawie funkcji)? Zmiana nazwy pliku i użytej funkcji wydaje się żmudna.
Bonlenfum,
11

W przypadku pierwszego pytania uważam, że dev.printnajlepiej jest pracować interaktywnie. Po pierwsze, skonfiguruj swój wykres wizualnie, a gdy będziesz zadowolony z tego, co widzisz, możesz poprosić R o zapisanie bieżącego wykresu na dysku

dev.print(pdf, file="filename.pdf");

Możesz zastąpić pdfinnymi formatami, takimi jak png.

Spowoduje to skopiowanie obrazu dokładnie tak, jak widzisz go na ekranie. Problem dev.copypolega na tym, że obraz jest często inny i nie pamięta rozmiaru okna i współczynnika proporcji - domyślnie wymusza kwadratowy wykres.

W przypadku drugiego pytania (jak już odpowiedzieli inni) musisz skierować dane wyjściowe na dysk przed wykonaniem poleceń drukowania

pdf('filename.pdf')
plot( yourdata )
points (some_more_data)
dev.off() # to complete the writing process and return output to your monitor
Aaron McDaid
źródło
8

Jeśli używasz R Studio http://rstudio.org/, istnieje specjalne menu, aby zapisać twoją fabułę w dowolnym formacie i dowolnej rozdzielczości.

efstratios charitos
źródło
4
To także istnieje przynajmniej w graficznym interfejsie użytkownika R.
richiemorrisroe
czasami to tajemniczo mi się nie udaje, ale wywoływanie funkcji zawsze działa
qwr
3

Jeśli otworzysz urządzenie za pomocą png(), bmp(), pdf()itd. Jak sugeruje Andrie (najlepsza odpowiedź), okna z działek nie pojawiają się otwarte, tylko * .png, * bmp lub * .pdf zostanie utworzony. Jest to wygodne w przypadku masowych obliczeń, ponieważ R może obsługiwać tylko ograniczoną liczbę okien graficznych.

Jeśli jednak chcesz zobaczyć wykresy i zapisać je, zadzwoń savePlot(filename, type)po narysowaniu wykresów i aktywnym oknie zawierającym je.

Alex Fainshtein
źródło
0

Aby dodać do tych odpowiedzi, jeśli masz skrypt R zawierający wywołania, które generują wykresy do ekranu (urządzenie macierzyste), wszystkie one można zapisać do pliku pdf (urządzenie domyślne dla powłoki nieinteraktywnej) "Rplots.pdf „(nazwa domyślna) poprzez przekierowanie skryptu do R z terminala (zakładając, że korzystasz z systemu Linux lub OS X), np .:

R < myscript.R --no-save

W razie potrzeby można to przekonwertować do formatu jpg / png

opłatek
źródło
0

W niektórych przypadkach chce się zarówno zapisać, jak i wydrukować podstawowy wykres r. Spędziłem trochę czasu i wymyśliłem tę funkcję narzędzia:

x = 1:10

basesave = function(expr, filename, print=T) {
  #extension
  exten = stringr::str_match(filename, "\\.(\\w+)$")[, 2]

  switch(exten,
         png = {
           png(filename)
           eval(expr, envir = parent.frame())
           dev.off()
         },
         {stop("filetype not recognized")})


  #print?
  if (print) eval(expr, envir = parent.frame())

  invisible(NULL)
}

#plots, but doesn't save
plot(x)

#saves, but doesn't plot
png("test.png")
plot(x)
dev.off()

#both
basesave(quote(plot(x)), "test.png")

#works with pipe too
quote(plot(x)) %>% basesave("test.png")

Należy pamiętać, że należy użyć quote, w przeciwnym razie plot(x)wywołanie zostanie uruchomione w środowisku globalnym i NULLzostanie przekazane do basesave().

Deleet
źródło
0
dev.copy(png,'path/pngFile.png')
plot(YData ~ XData, data = mydata)
dev.off()
orientchen1978
źródło