9 votos

Creando mapa animado utilizando R

Estoy siendo bastante nuevo con R.

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

introducir descripción de la imagen aquí

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="Desempleo en Rusia por región")

El resultado, que deseo obtener es algo así como la animación aquí: http://spatial.ly/2011/02/mapping-londons-population-change-2011-2030/ Sin embargo, he buscado mucho, leí una serie de temas en http://stackoverflow.com incluyendo el siguiente: Creando una película a partir de una serie de gráficos en R, pero aún no pude hacer lo correcto.

He llegado a algo como esto.

¿Alguien puede decirme dónde está mi 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="Desempleo en Rusia por región")
},img.name = "map", htmlfile = "unrus2.html")

0 votos

Re la edición: ¿qué está saliendo mal con el código?

0 votos

Dado que tu ejemplo no es reproducible, es difícil de solucionar. Algunas cosas a tener en cuenta son: 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 nombres de columna reales, es decir, for(i in c("Var1","Var2")). La forma en que actualmente lo tienes codificado es muy confusa. 4) tu llamada a spplot no es correcta, estás pasándole un vector sin sentido.

0 votos

Realmente lo siento por no entender mucho, pero esta es mi primera experiencia real con R. He agregado los datos en la pregunta principal. Si no te importa, ¿puedes sugerir formas de mejorar? Realmente me quedé sin ideas.

9voto

Dan Puntos 16

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

Usar la función "saveHTML" en el paquete de animación es muy sencillo. Aquí tienes un código de ejemplo donde creo una animación de un cambio poblacional aleatorio. El argumento "expr" define la función de graficación que quieres pasar a la animación. Como puedes ver en el código a continuación, utilicé un bucle for para graficar cada columna simulada.

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

# Carga tus datos y añade una columna de cambio poblacional aleatorio
    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) 
       }

# Crea una animación HTML usando un bucle for para cada columna simulada    
    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("Cambio Poblacional",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="CambioPobAleatorio", htmlfile="SimCambioPoblacional.html",
           single.opts = "'controls': ['first', 'previous', 'play', 'next', 'last', 'loop', 'speed'], 'delayMin': 0",      
            description=c("Cambio poblacional aleatorio:"))  

Edité la publicación para proporcionar un ejemplo más relevante basado en columnas de polígonos.

0 votos

Gracias, Sin embargo, esto es lo primero que realmente hice, comencé a explorar esta pregunta, sin embargo no me dio el resultado ya que no entendí qué expresión debería ser como argumento.

0 votos

Oh, creo que es apropiado, intentaré optimizarlo para mis necesidades tan pronto como termine con la preparación de datos. Muchas gracias, tan pronto como funcione aceptaré una respuesta. Y justo la pregunta que surge de inmediato: ¿es posible usar spplot aquí en lugar de plot, no lo has intentado?

0 votos

He editado la pregunta principal para mostrar mis ideas sobre tu código, pero estoy seguro de que he cometido varios errores ya que no funciona correctamente. ¿Puedes ayudar con esto?

7voto

Markus Olsson Puntos 12651

La animación que has enlazado (abajo) es una imagen animada en formato GIF.

introducir descripción de la imagen aquí

Essencialmente, es una serie de imágenes que se ciclan, lo que crea el efecto de animación. Piensa en ello como si estuvieras pasando por una serie de diapositivas, una cada segundo aproximadamente.

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

1) Crear cada 'cuadro' individual que se mostrará.

2) Crear el GIF en sí. Hay varios sitios web que pueden hacer esto por ti:

http://www.createagif.net/

http://makeagif.com/

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

La pregunta de StackOverflow a la que enlazaste debería proporcionarte todo lo que necesitas saber para realizar esta tarea en R. Observa que primero debes instalar un paquete de terceros.

EDITAR: A continuación se presenta 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 una de las parcelas individuales que has creado en R y las convierte en una animación recorriendo cada una y utilizando ImageMagick, el cual debes tener instalado.

0 votos

Gracias, pero soy amable tengo una necesidad de animación que se haga dentro de R sin necesidad de otros sitios web y realmente no entiendo cómo funciona este código e idea en stockoverflow, de lo contrario ni siquiera preguntaría.

0 votos

Creo que la respuesta de Stack Exchange puede ser un poco confusa porque la respuesta separó el código con un bloque de texto. 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 pueden ser estúpidos y fáciles, pero desafortunadamente no tengo experiencia en manejarlos. 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 menciona la no existencia de la función my.plot, aunque todo lo que se ha figurado aquí está instalado. Puede que sea yo quien está operando incorrectamente, si puedes por favor darme algún consejo. Gracias de antemano.

5voto

Dan Puntos 16

Esto es hasta donde llego. Deberías ser capaz de entenderlo basándote en este código. Una vez más, como tu problema no es reproducible, tuve que crear datos ficticios para ilustrar la solución. Un aspecto extraño al usar spplot es que ya que utiliza lattice para crear el gráfico, necesitas crear un objeto y luego imprimirlo. De lo contrario, no obtendrás 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()

# Establecer paleta de colores
myPalette <- brewer.pal(6,"Purples")

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

# Crear datos de desempleo ficticios con un cambio del 10% en el objeto gadm
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) 

# Convertir en factores con niveles definidos
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("Desempleo en Rusia", i, sep=" - ") )
      print( sp.plot )
},img.name = "map", htmlfile = "unrus2.html")

0 votos

¡Gracias! Lo intentaré de inmediato. Solo una pregunta gadm@data$uemp2001 <- gadm@data$uemp2000 + (gadm@data$uemp2000 * 0.10) ¿puedo cargar aquí datos txt en lugar de los aleatorios dados, no se realizará ninguna solución de problemas?

0 votos

Sí, ese código está simplemente asociado con la creación de datos de ejemplo. Querrías usar tus propios datos.

2voto

Dani Duran Puntos 481

Aquí está 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

¡Oh, me gusta el uso de la librería de espaciotiempo!

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