9 votos

Hacer un mapa animado con R

Estoy siendo bastante nuevo con R.

Quiero crear un mapa animado de Russin con los cambios en el desempleo con diferentes años, como. En la imagen se pueden ver los datos de un año.

enter image description here

require(sp)
require(maptools)

require(RColorBrewer)
require(rgdal)
 rus<-url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData")
print(load(rus))

unempl <- read.delim2(file="C:\\unempl1.txt", header = TRUE, 
        sep = ";",quote = "", dec=",", stringsAsFactors=F)

gadm_names <-gadm$NAME_1
total <- length(gadm_names)
pb <- txtProgressBar(min = 0, max = total, style = 3) 

order <- vector()
for (i in 1:total){  

  order[i] <- agrep(gadm_names[i], unempl$region, 
                     max.distance = 0.2)[1]
 setTxtProgressBar(pb, i)               # update progress bar
}

col_no <- as.factor(as.numeric(cut(unempl$data[order],
                    c(0,2.5,5,7.5,10,15,100))))

levels(col_no) <- c("<2,5%", "2,5-5%", "5-7,5%",
                    "7,5-10%", "10-15%", ">15%")

gadm$col_no <- col_no
myPalette<-brewer.pal(6,"Purples")

proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)

spplot(gadm.prj, "col_no", col=grey(.9), col.regions=myPalette,
main="Unemployment in Russia by region")

El resultado, que estoy dispuesto a obtener es algo como la animación aquí: http://spatial.ly/2011/02/mapping-londons-population-change-2011-2030/ Sin embargo, busqué mucho en Google, leí varios temas en http://stackoverflow.com incluyendo lo siguiente: Creación de una película a partir de una serie de gráficos en R pero todavía no podía hacer lo correcto.

Gracias por adelantado.

Se me ha ocurrido algo así, ¿alguien puede decirme dónde está el error?

require(animation)
    require(sp)
    require(RColorBrewer) 
    require(classInt)     
require(rgdal)
 rus<-url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData")
print(load(rus))

unempl1 <- read.delim2(file="C:\\unempl11.txt", header = TRUE, 
        sep = ";",quote = "", dec=",", stringsAsFactors=F)
unempl2<- read.delim2(file="C:\\unempl12.txt", header = TRUE, 
        sep = ";",quote = "", dec=",", stringsAsFactors=F)

gadm_names <-gadm$NAME_1

total <- length(gadm_names)
pb <- txtProgressBar(min = 0, max = total, style = 3) 

order <- vector()

for (i in 1:total){  

  order[i] <- agrep(gadm_names[i], unempl1$region, 
                     max.distance = 0.2)[1]
 setTxtProgressBar(pb, i)               # update progress bar
}

for (l in 1:total){  

  order[l] <- agrep(gadm_names[l], unempl2$region, 
                     max.distance = 0.2)[1]
 setTxtProgressBar(pb, i)               # update progress bar
}

col_no_1 <- as.factor(as.numeric(cut(unempl1$data[order],
                    c(0,2.5,5,7.5,10,15,100))))

col_no_2<- as.factor(as.numeric(cut(unempl2$data[order],
                    c(0,2.5,5,7.5,10,15,100))))
saveHTML(
      for(k in 1:2) {
        try<-get(paste("col_no_", k, sep = ""))

levels(try) <- c("<2,5%", "2,5-5%", "5-7,5%",
                    "7,5-10%", "10-15%", ">15%")

gadm$col_no <- try

myPalette<-brewer.pal(6,"Purples")

proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)

spplot(gadm.prj, "col_no", col=grey(.9), col.regions=myPalette,
main="Unemployment in Russia by region")
},img.name = "map", htmlfile = "unrus2.html")

Aquí están los datos para poder reproducir el código

0 votos

Re La edición: ¿qué está fallando en el código?

0 votos

Dado que su ejemplo no es reproducible, es difícil solucionar el problema. Algunas cosas saltan a la vista 1) estás aplicando una transformación espacial en un bucle, por lo que lo estás haciendo repetidamente 2) estás creando un objeto llamado "try" que también es una función de R 3) podrías iterar a través de los nombres de las columnas reales, es decir, for(i in c("Var1", "Var2")) la forma en que actualmente lo tienes codificado es muy enrevesada 4) tu llamada a spplot no es correcta, le estás pasando un vector sin sentido.

0 votos

Siento mucho ser un incomprendido, pero esta es mi primera experiencia real con R, he añadido los datos en la pregunta principal, si no te molesta puedes sugerir maneras de mejorar ya que realmente me quedé sin ideas

9voto

Dan Puntos 16

Echa un vistazo a la animación paquete. Una de las funciones que vale la pena explorar, que no requiere software de terceros, es "saveHTML".

El uso de la función "saveHTML" en el paquete de animación es muy sencillo. Aquí está el código de ejemplo donde creo una animación de un cambio de población aleatorio. El argumento "expr" define la función de trazado que se quiere pasar a la animación. Como se puede ver en el código de abajo he utilizado un bucle for para trazar cada columna simulada.

    require(animation)
    require(sp)
    require(RColorBrewer) 
    require(classInt)     

# Load your data and add random population change column
    load(url("http://www.gadm.org/data/rda/GBR_adm2.RData"))
      for( i in 1:10 ) {
        gadm@data[paste("Year",i, sep="")] <- runif(dim(gadm)[1],0,1) 
       }

# Create HTML animation using for loop for each simulated column    
    saveHTML(
      for(x in names(gadm@data)[19:28]) { 
      ani.options(interval = 0.5)  
       plotvar <- gadm@data[,x]
          nclr <- 9
         plotclr <- rev(brewer.pal(nclr,"BuPu"))
          cuts <- classIntervals(plotvar, style="fixed", 
               fixedBreaks=c(0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,1))
               colcode <- findColours(cuts, plotclr)
          plot(gadm, col=colcode, border=NA, ylim=c(bbox(gadm)[,1][2], bbox(gadm)[,2][2]),
            xlim=c(bbox(gadm)[,1][1], bbox(gadm)[,2][1]))
            text(min(bbox(gadm)[1]), min(bbox(gadm)[2]), paste("Population Change",x,sep=" "))
          box()
        legend("topleft", legend=c("0-10%","10-20%","20-30%","30-40%","40-50%",
               "50-60%","60-70%","70-80%","80-100%"),
                 fill=attr(colcode, "palette"), cex=0.6, bty="n")   
        ani.pause() 
        },
           img.name="RandPopChange", htmlfile="SimPopChange.html",
           single.opts = "'controls': ['first', 'previous', 'play', 'next', 'last', 'loop', 'speed'], 'delayMin': 0",      
            description=c("Random population change:"))  

He editado el post para ofrecer un ejemplo más relevante basado en columnas de polígonos.

0 votos

Gracias, Sin embargo, esto es lo primero que hice, empezando a explorar esta cuestión, sin embargo no me dio el resultado ya que no pude entender que expresión debe ser como argumento.

0 votos

Oh, creo que es apropiado, trataré de optimizarlo para mis necesidades tan pronto como termine con la preparación de los datos. Muchas gracias, en cuanto funcione aceptaré una respuesta. Y sólo la pregunta que surge de inmediato: ¿es posible utilizar spplot aquí en lugar de parcela, no has probado?

0 votos

He editado la pregunta principal para mostrar mis ideas en relación con su código, pero estoy seguro de que he cometido varios errores ya que no funciona correctamente. ¿Puede ayudarme con esto?

7voto

Markus Olsson Puntos 12651

La animación que has enlazado (más abajo) es un Imagen GIF .

enter image description here

Se trata esencialmente de una serie de imágenes que se recorren cíclicamente, lo que crea el efecto de animación. Piensa en ello como si hicieras clic en una serie de diapositivas, una cada segundo más o menos.

Lo que tienes que hacer para crear la animación es:

1) Cree cada uno de los "marcos" que se mostrarán.

2) Crear el propio GIF. Hay varios sitios web que lo hacen por ti:

http://www.createagif.net/

http://makeagif.com/

La mayoría de estos sitios web le permitirán controlar el tamaño y la velocidad de la animación.

El Pregunta de StackOverflow a la que has enlazado debería proporcionarle todo lo que necesita saber para realizar esta tarea en R. Tenga en cuenta que primero tiene que instalar un paquete de terceros.

EDITAR : A continuación hay una versión actualizada del código del enlace de StackOverflow anterior ya que parece haber un poco de confusión.

jpeg("/tmp/foo%02d.jpg")
for (i in 1:5) {
  my.plot(i)
}      
make.mov <- function(){
     unlink("plot.mpg")
     system("convert -delay 0.5 plot*.jpg plot.mpg")
}

dev.off()

Este código anterior toma cada uno de los gráficos individuales que ha creado en R y los convierte en una animación haciendo un bucle sobre cada uno y utilizando ImageMagick que debe tener instalado.

0 votos

Gracias, pero soy un tipo tienen una necesidad de animación que se hace dentro de R sin otros sitios web y realmente no entiendo cómo funciona este código y la idea en stockoverflow, de lo contrario ni siquiera preguntar

0 votos

Creo que la respuesta del intercambio de pilas puede ser un poco confusa porque la respuesta separaba el código con un bloque de texto. Voy a editar mi respuesta con una versión actualizada de ese código.

0 votos

Gracias por la actualización, pero todavía hay un número de problemas, que puede ser estúpido y fácil, pero por desgracia no tengo experiencia en la gestión de ellos. Si no te importa te preguntaré:1) ¿Qué significa jpeg(...) en este código? ya que Rstudio da un error de no poder abrir el archivo 2) Rstudio dice sobre la inexistencia de la función my.plot, aunque todo lo que se ha explicado aquí está instalado. Puede ser que sea yo quien opere mal, si puedes por favor dar algún consejo. Gracias de antemano.

5voto

Dan Puntos 16

Hasta aquí he llegado. Usted debe ser capaz de averiguar sobre la base de este código. Una vez más, como tu problema no es reproducible he tenido que crear datos ficticios para ilustrar la solución. Un aspecto impar en el uso de spplot es que como utiliza lattice para crear el gráfico necesitas crear un objeto y luego imprimir el objeto. De lo contrario, no se obtiene un gráfico.

require(animation)
require(sp)
require(RColorBrewer) 
require(classInt)     
require(rgdal)

load(url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData"))
closeAllConnections()

# Set color palette
myPalette <- brewer.pal(6,"Purples")

# Reproject data
gadm <- spTransform(gadm, CRS("+init=epsg:3413 +lon_0=105"))

# Create dummy unployment data with 10% change in gadm object 
gadm@data$uemp2000 <- runif(dim(gadm)[1],0,50)
gadm@data$uemp2001 <- gadm@data$uemp2000 + (gadm@data$uemp2000 * 0.10) 
gadm@data$uemp2002 <- gadm@data$uemp2001 + (gadm@data$uemp2001 * 0.10) 
gadm@data$uemp2003 <- gadm@data$uemp2002 + (gadm@data$uemp2002 * 0.10) 
gadm@data$uemp2004 <- gadm@data$uemp2003 + (gadm@data$uemp2003 * 0.10) 
gadm@data$uemp2005 <- gadm@data$uemp2004 + (gadm@data$uemp2004 * 0.10) 

# Coerce into factors with defined levels
for( i in c("uemp2000","uemp2001","uemp2002","uemp2003","uemp2004","uemp2005") ) {
  gadm@data[,i] <- as.factor(as.numeric(cut(gadm@data[,i], 
                             c(0,2.5,5,7.5,10,15,100)))) 
    levels(gadm@data[,i]) <- c("<2,5%", "2,5-5%", "5-7,5%",
                               "7,5-10%", "10-15%", ">15%")                          
    } 

saveHTML(
  for(i in c("uemp2000","uemp2001","uemp2002","uemp2003","uemp2004","uemp2005")) {
    sp.plot <- spplot(gadm, i, col=grey(.9), col.regions=myPalette,
                      main=paste("Unemployment in Russia", i, sep=" - ") )
      print( sp.plot )
},img.name = "map", htmlfile = "unrus2.html")

0 votos

Gracias. Lo probaré inmediatamente. Sólo una pregunta gadm@data $uemp2001 <- gadm@data$ uemp2000 + (gadm@data$uemp2000 * 0.10) ¿puedo aquí cargar los datos txt en lugar de los dados al azar, no se producirá la resolución de problemas?

0 votos

Sí, ese código sólo está asociado a la creación de datos de ejemplo. Usted querrá utilizar sus propios datos.

2voto

Dani Duran Puntos 481

Aquí es la respuesta, gracias a Oscar Perpiñán.

library(sp)
library(rgdal)
library(spacetime)
library(animation)
rus <- url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData")
load(rus)
proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)
N <- nrow(gadm.prj)
pols <- geometry(gadm.prj)
nms<-gadm$NAME_1
vals1  <- read.csv2("C:\\unempl11.txt")
ord1 <- match(nms, vals1$region)
vals1 <- vals1[ord1,]

vals2 <- read.csv2("C:\\unempl12.txt")
ord2 <- match(nms, vals2$region)
vals2 <- vals2[ord2,]

nDays <- 2
tt <- seq(as.Date('2011-01-01'), by='year', length=nDays)
vals <- data.frame(unempl=rbind(vals1, vals2)[,-1])

gadmST <- STFDF(pols, time=tt, data=vals)

stplot(gadmST, animate=1, do.repeat=FALSE)

saveHTML(stplot(gadmST, animate=1, do.repeat=FALSE)
, img.name = "unemplan",  htmlfile = "unan.html")

0 votos

Ooh, ¡me gusta el uso de la biblioteca del espacio-tiempo!

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X