2015-11-03 10 views
5

Sto cercando un metodo automatizzato per convertire i grafici di Studio leaflet R Studio in file immagine.Creare una gif da una serie di mappe Leaflet in R

Sembra esportare un widget leaflet in HTML è semplice (Saving leaflet output as html). Tuttavia non riesco a trovare alcuna risposta o documento su come salvare l'immagine prodotta da un widget leaflet come un'immagine. Sembra strano che io possa farlo manualmente in R Studio ma non ci sono alcune funzioni all'interno di R Studio che possono essere chiamate per fare la stessa cosa.

ho provato i soliti sospetti, le variazioni su quanto segue:

png("test_png.png") 
map 
dev.off() 

Ma questi tutto solo stampare bianco o stampare un file che non può nemmeno essere aperto. Se ho capito bene questo Git discussion, sembra che qualcosa in leaflet non sia disponibile ma è desiderato dagli utenti.

Nel frattempo, R Studio ha chiaramente un modo per rendere questa immagine in un file immagine, facendomi premere un pulsante per farlo. C'è un modo per automatizzare questo? Come posso esportare le immagini tracciate in R Studio in file di immagini? Ho bisogno di file di immagine e ho bisogno che questo sia programmatico perché voglio fare uno gif su poche centinaia di mappe.

In alternativa, mi piacerebbe ricevere suggerimenti per una soluzione alternativa. Potrei provare questo: Python - render HTML content to GIF image ma se qualcuno ha suggerimenti alternativve, si prega di condividere.

+0

Quello che ho fatto in una situazione simile è quello di creare tutte le mappe e salvarle come file html. Quindi crea un altro file html che manterrà semplicemente un iframe che legge i file della tua mappa. Dovrai imparare un po 'di javascript, ma puoi creare un ciclo che cicla attraverso i file html all'interno del tuo iframe per una gif di fortuna. Non sono sicuro che questo funzioni per la tua situazione, ma ho pensato di buttarlo là fuori. – brittenb

+1

@brittenb In realtà ho usato questa soluzione in passato, ed è probabilmente adatta a ciò che voglio fare qui comunque. Il lato positivo di ciò è che non sono sposato con 1 gif, ma posso combinare ciò che mi piace. post scriptum Mi piace il tuo profilo; P – sunny

risposta

8

Ho cercato di farlo con una combinazione del pacchetto webshot e saveWidget da htmltools, anche se è piuttosto lento. Per alcune centinaia di mappe, probabilmente non è così male se lo fai solo qui e là. Ma per l'applicazione in tempo reale è troppo lento.

Esistono due applicazioni esterne necessarie per questo flusso di lavoro. webshot prende screenshot di pagine web e richiede di installare PhantomJS prima (è piccolo e facile). Io uso anche ImageMagick (e deve essere accessibile dalla riga di comando) per creare i file .gif, ma sono sicuro che ci sono molti altri programmi che potresti usare per creare gif.

L'idea è solo quella di creare le mappe in un ciclo, salvarle in un file html temporaneo con saveWidget e utilizzare webshot per trasformarlo in un png (lento). Quindi, una volta che hai tutti i png, usa ImageMagick per convertirli in una gif (veloce).

Ecco un esempio, carico anche ggmap, ma solo per ottenere una posizione per ingrandire.

library(webshot) 
library(leaflet) 
library(htmlwidgets) 
library(ggmap) 

loc <- geocode('mt everest') # zoom in everest 
zooms <- seq(2,14,3)   # some zoom levels to animate 

## Make the maps, this will make some pngs called 'Rplot%02d.png' 
## in your current directory 
for (i in seq_along(zooms)) { 
    m <- leaflet(data=loc) %>% 
     addProviderTiles('Esri.WorldImagery') %>% 
     setView(lng=loc$lon, lat=loc$lat, zoom=zooms[i]) 
    if (i==1) 
     m <- m %>% addPopups(popup="Going to see Mt Everest") 
    if (i==length(zooms)) 
     m <- m %>% 
      addCircleMarkers(radius=90, opacity = 0.5) %>% 
      addPopups(popup = 'Mt Everest') 

    ## This is the png creation part 
    saveWidget(m, 'temp.html', selfcontained = FALSE) 
    webshot('temp.html', file=sprintf('Rplot%02d.png', i), 
      cliprect = 'viewport') 
} 

Quindi, è solo la conversione di png in gif. L'ho fatto su un Windows, quindi il comando potrebbe essere leggermente diverso su un Mac/Linux (penso solo a virgolette singole invece di virgolette doppie o qualcosa del genere). Questi comandi provengono da una riga di comando/shell, ma è anche possibile utilizzare system/system2 per chiamare da R o provare il pacchetto animation con alcune funzioni wrapper per ImageMagick. Fare una semplice gif senza niente è semplicemente, convert *.png animation.gif. Ho usato un codice leggermente più lungo per rendere i png più piccoli/aggiungere alcuni ritardi/e far entrare e uscire la sequenza.

convert Rplot%02d.png[1-5] -duplicate 1,-2-1, -resize "%50" gif:- | convert - -set delay "%[fx:(t==0||t==4)?240:40]" -quiet -layers OptimizePlus -loop 0 cycle.gif 

enter image description here

+0

Ottima risposta - bella tecnica. –

+0

Wow, grazie mille. Ho imparato molto dalla tua risposta dettagliata. – sunny

0

devo tabella con 3 colonne: lat, lon, giorno (376 giorni).

Il processo è: creare la mappa -> salvare la mappa come HTML -> salvare la mappa come PNG -> importare il pic -> plot esso (con la trama + ggimage)

Tutto questo processo, sarà in un ciclo

library(leaflet) 
library(animation) 
library(png) 
library(htmlwidgets) 
library(webshot) 
library(ggmap) 

saveGIF({ 
for (i in 1:376) { 
    map = leaflet() %>% 
    addTiles() %>% 
    setView(lng = lon_lat[1,2], lat = lon_lat[1,1], zoom = 5)%>% 
    addMarkers(lng = lon_lat[lon_lat$day == i,2],lat = lon_lat[lon_lat$day == i,1]) 

    saveWidget(map, 'temp.html', selfcontained = FALSE) ## save the html 
    webshot('temp.html', file=sprintf('Rplot%02d.png', 1),cliprect = 'viewport') ## save as png 
    img = readPNG("Rplot01.png") ### read the png 
    plot(ggimage(img)) ###reading png file 
} 
}) 
0

È possibile creare una serie di file PNG come risposta da jenesaisquoi (prima risposta). Quindi crea gif con i file png usando il codice seguente con il pacchetto magick.

library(magick) 

    png.files <- sprintf("Rplot%02d.png", 1:20) #Mention the number of files to read 
GIF.convert <- function(x, output = "animation.gif")#Create a function to read, animate and convert the files to gif 
     { 
     image_read(x) %>% 
     image_animate(fps = 1) %>% 
     image_write(output) 
     } 

     GIF.convert(png.files) 

Non è necessario installare il software ImageMagick su PC.

Codice Link: Animation.R