Cómo configurar el uso de ggplot2 para mapear un ráster


Me gustaría hacer una gráfica usando R studio similar a la siguiente (creada en Arc Map)

introduzca la descripción de la imagen aquí

He intentado el siguiente código:

# data processing
library(ggplot2)
# spatial
library(raster)
library(rasterVis)
library(rgdal)

#
test <- raster(paste(datafold,'oregon_masked_tmean_2013_12.tif',sep="")) # read the temperature raster
OR<-readOGR(dsn=ORpath, layer="Oregon_10N") # read the Oregon state boundary shapefile

gplot(test) +  
  geom_tile(aes(fill=factor(value),alpha=0.8)) + 
  geom_polygon(data=OR, aes(x=long, y=lat, group=group), 
               fill=NA,color="grey50", size=1)+
  coord_equal()

La salida de ese código se ve así:

introduzca la descripción de la imagen aquí

Un par de cosas a tener en cuenta. En primer lugar, los shapefiles de la cuenca faltan en la versión R. eso está bien.

En segundo lugar, El fondo gris más oscuro en el gráfico R no es ningún valor de datos. En Arc, no se muestran, pero en R mostrar con gplot. No se muestran cuando uso 'plot'del paquete raster:

plot(test)

introduzca la descripción de la imagen aquí

Mis preguntas son las siguientes:

  1. ¿Cómo puedo eliminar el relleno de NoData gris oscuro en el ejemplo 'gplot'?
  2. ¿Cómo puedo configurar la leyenda (barra de color) para que sea razonable (como en las leyendas de 'parcela' de ArcMap y raster?)
  3. ¿Cómo puedo controlar el mapa de colores?

Para tener en cuenta, he probado muchas versiones diferentes de

scale_fill_brewer
scale_fill_manual
scale_fill_gradient

Y así en y así sucesivamente, pero tengo errores, por ejemplo

br <- seq(minValue(test), maxValue(test), len=8)

gplot(test)+
geom_tile(aes(fill=factor(value),alpha=0.8)) +

scale_fill_gradient(breaks = br,labels=sprintf("%.02f", br)) +

geom_polygon(data=OR, aes(x=long, y=lat, group=group), 
             fill=NA,color="grey50", size=1)+
coord_equal()

Regions defined for each Polygons
Error: Discrete value supplied to continuous scale

Finalmente, una vez que tengo una solución para conspirar uno de estos mapas, me gustaría parcela de varios mapas en una figura y crear un único colorbar para todo el panel (es decir, un colorbar para todos los mapas) y me gustaría ser capaz de controlar donde el colorbar se encuentra y el tamaño de la colorbar. Aquí hay un ejemplo de lo que puedo hacer con grid.organizar, pero no puedo averiguar cómo establecer una sola barra de color:

r1 <- test
r2 <- test
r3 <- test
r4 <- test

colr <- colorRampPalette(rev(brewer.pal(11, 'RdBu')))

l1 <- levelplot(r1, 
          margin=FALSE,                       
          colorkey=list(
             space='bottom',                   
             labels=list(at=-5:5, font=4),
             axis.line=list(col='black')       
          ),    
          par.settings=list(
             axis.line=list(col='transparent') 
          ),
          scales=list(draw=FALSE),            
          col.regions=viridis,                   
          at=seq(-5, 5, len=101)) +           
   layer(sp.polygons(oregon, lwd=3))

l2 <- levelplot(r2, 
                margin=FALSE,                       
                colorkey=list(
                   space='bottom',                   
                   labels=list(at=-5:5, font=4),
                   axis.line=list(col='black')       
                ),    
                par.settings=list(
                   axis.line=list(col='transparent') 
                ),
                scales=list(draw=FALSE),            
                col.regions=viridis,                   
                at=seq(-5, 5, len=101)) +           
   layer(sp.polygons(oregon, lwd=3))

l3 <- levelplot(r3, 
                margin=FALSE,                       
                colorkey=list(
                   space='bottom',                   
                   labels=list(at=-5:5, font=4),
                   axis.line=list(col='black')       
                ),    
                par.settings=list(
                   axis.line=list(col='transparent') 
                ),
                scales=list(draw=FALSE),            
                col.regions=viridis,                   
                at=seq(-5, 5, len=101)) +           
   layer(sp.polygons(oregon, lwd=3))

l4 <- levelplot(r4, 
                margin=FALSE,                       
                colorkey=list(
                   space='bottom',                   
                   labels=list(at=-5:5, font=4),
                   axis.line=list(col='black')       
                ),    
                par.settings=list(
                   axis.line=list(col='transparent') 
                ),
                scales=list(draw=FALSE),            
                col.regions=viridis,                   
                at=seq(-5, 5, len=101)) +           
   layer(sp.polygons(oregon, lwd=3))

grid.arrange(l1, l2, l3, l4,nrow=2,ncol=2) #use package gridExtra   

El la salida es la siguiente:

introduzca la descripción de la imagen aquí

El shapefile y el archivo raster están disponibles en el siguiente enlace:

Https://drive.google.com/open?id=0B5PPm9lBBGbDTjBjeFNzMHZYWEU

Muchas gracias por adelantado.

Devtools:: session_info() Información de la sesión --------------------------------------------------------------------------------------------------------------------- valor de ajuste
versión R versión 3.1.1 (2014-07-10) sistema x86_64, darwin10.8.0
ui RStudio (0.98.1103)
language (EN)
intercalar en_US.UTF-8
tz America / Los_Angeles

Paquetes ------------------------------------------------------------------------------------------------------------------------- paquete * versión fecha fuente
bitops 1.0 - 6 2013-08-17 CRAN (R 3.1.0) colorspace 1.2-6 2015-03-11 CRAN (R 3.1.3) devtools 1.8.0 2015-05-09 CRAN (R 3.1.3) digerir 0.6.4 2013-12-03 CRAN (R 3.1.0) ggplot2 * 1.0.1 2015-03-17 CRAN (R 3.1.3) ggthemes * 2.1.2 2015-03-02 CRAN (R 3.1.3) git2r 0.10.1 2015-05-07 CRAN (R 3.1.3) gridExtra 0.9.1 2012-08-09 CRAN (R 3.1.0) gtable 0.1.2 2012-12-05 CRAN (R 3.1.0) hexbin * 1.26.3 2013-12-10 CRAN (R 3.1.0) celosía * 0.20-29 2014-04-04 CRAN (R 3.1.1) latticeExtra * 0.6-26 2013-08-15 CRAN (R 3.1.0) magrittr 1.5 2014-11-22 CRAN (R 3.1.2) MASA 7.3-33 2014-05-05 CRAN (R 3.1.1) memoise 0.2.1 2014-04-22 CRAN (R 3.1.0) munsell 0.4.2 2013-07-11 CRAN (R 3.1.0) plyr 1.8.2 2015-04-21 CRAN (R 3.1.3) proto 0.3 - 10 2012-12-22 CRAN (R 3.1.0) raster * 2.2-31 2014-03-07 CRAN (R 3.1.0) rasterVis * 0.28 2014-03-25 CRAN (R 3.1.0) RColorBrewer * 1.0-5 2011-06-17 CRAN (R 3.1.0) Rcpp 0.11.2 2014-06-08 CRAN (R 3.1.0) RCurl 1.95 - 4.6 2015-04-24 CRAN (R 3.1.3) reshape2 1.4.1 2014-12-06 CRAN (R 3.1.2) rgdal * 0.8-16 2014-02-07 CRAN (R 3.1.0) rversions 1.0.0 2015-04-22 CRAN (R 3.1.3) escalas * 0.2.4 2014-04-22 CRAN (R 3.1.0) sp * 1.0-15 2014-04-09 CRAN (R 3.1.0) stringi 0.4-1 2014-12-14 CRAN (R 3.1.2) stringr 1.0.0 2015-04-30 CRAN (R 3.1.3) viridis * 0.3.1 2015-10-11 CRAN (R 3.2.0) XML 3.98-1.1 2013-06-20 CRAN (R 3.1.0) zoo 1.7-11 2014-02-27 CRAN (R 3.1.0)

Author: mr. cooper, 2015-10-20

3 answers

Así es como lo haría, con rasterVis::levelplot:

Cargar cosas:

library(rgdal)
library(rasterVis)
library(RColorBrewer)

Lee las cosas:

oregon <- readOGR('.', 'Oregon_10N')
r <- raster('oregon_masked_tmean_2013_12.tif')

Defina una paleta de rampa de color (o un vector de colores con una longitud 1 más corta que el número de roturas para la rampa de color definida con el argumento at a continuación).

colr <- colorRampPalette(brewer.pal(11, 'RdYlBu'))

Trazar cosas:

levelplot(r, 
          margin=FALSE,                       # suppress marginal graphics
          colorkey=list(
            space='bottom',                   # plot legend at bottom
            labels=list(at=-5:5, font=4)      # legend ticks and labels 
          ),    
          par.settings=list(
            axis.line=list(col='transparent') # suppress axes and legend outline
          ),
          scales=list(draw=FALSE),            # suppress axis labels
          col.regions=colr,                   # colour ramp
          at=seq(-5, 5, len=101)) +           # colour ramp breaks
  layer(sp.polygons(oregon, lwd=3))           # add oregon SPDF with latticeExtra::layer

introduzca la descripción de la imagen aquí

Es posible que desee trazar el contorno de la leyenda (incluidas sus marcas), en cuyo caso agregue axis.line=list(col='black') a la lista de colorkey args. Esto es necesario para anular la supresión general de cajas causada por par.settings=list(axis.line=list(col='transparent')):

levelplot(r, 
          margin=FALSE,                       
          colorkey=list(
            space='bottom',                   
            labels=list(at=-5:5, font=4),
            axis.line=list(col='black')       
          ),    
          par.settings=list(
            axis.line=list(col='transparent') 
          ),
          scales=list(draw=FALSE),            
          col.regions=colr,                   
          at=seq(-5, 5, len=101)) +           
  layer(sp.polygons(oregon, lwd=3))                  

introduzca la descripción de la imagen aquí

Estoy de acuerdo con @hrbrmstr en que viridis es a menudo una mejor rampa para usar, a pesar de ser being en mi opinión.un poco feo. Los principales beneficios sobre algo como ColorBrewer RdYlBu son que los colores siguen siendo distintos cuando están desaturados, y las diferencias de color reflejan mejor las diferencias en los valores. Creo que RdYlBu es perfectamente accesible para Deuteranopía/Protanopía / Tritanopía daltonismo, sin embargo.

Aquí está la versión de viridis:

library(viridis)
levelplot(r, 
          margin=FALSE,                       
          colorkey=list(
            space='bottom',                   
            labels=list(at=-5:5, font=4),
            axis.line=list(col='black')       
          ),    
          par.settings=list(
            axis.line=list(col='transparent') 
          ),
          scales=list(draw=FALSE),            
          col.regions=viridis,                   
          at=seq(-5, 5, len=101)) +           
  layer(sp.polygons(oregon, lwd=3))

introduzca la descripción de la imagen aquí


EDITAR

En respuesta a la pregunta adicional de OP, aquí está cómo trazar varios rásters según lo solicitado.

Suponiendo que todos los rásters tienen la misma extensión, resolución, proyecciones, etc., puede apilarlos en un RasterStack, y luego usar levelplot en la pila. Puede pasar width como un elemento de la lista pasada a colorkey para controlar la altura de la leyenda ("width" es un poco contra-intuitivo, pero por defecto las leyendas son verticales). Si desea suprimir las etiquetas de tira por encima de cada panel (como he hecho a continuación - por defecto se etiquetan con los nombres de capa de la pila [ver names(s)]), puede agregar strip.border y strip.background a la lista pasada a par.settings.

s <- stack(r, r*0.8, r*0.6, r*0.4)
levelplot(s, 
          margin=FALSE,                       
          colorkey=list(
            space='bottom',                   
            labels=list(at=-5:5, font=4),
            axis.line=list(col='black'),
            width=0.75
          ),    
          par.settings=list(
            strip.border=list(col='transparent'),
            strip.background=list(col='transparent'),
            axis.line=list(col='transparent')
          ),
          scales=list(draw=FALSE),            
          col.regions=viridis,                   
          at=seq(-5, 5, len=101),
          names.attr=rep('', nlayers(s))) +           
  layer(sp.polygons(oregon, lwd=3))

introduzca la descripción de la imagen aquí

 13
Author: jbaums,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-24 00:58:32
library(ggplot2)
library(raster)
library(rasterVis)
library(rgdal)
library(grid)
library(scales)
library(viridis)  # better colors for everyone
library(ggthemes) # theme_map()

datafold <- "/path/to/oregon_masked_tmean_2013_12.tif"
ORpath <- "/path/to/Oregon_10N.shp"

test <- raster(datafold) 
OR <- readOGR(dsn=ORpath, layer="Oregon_10N") 

No incluiste lo que estabas usando para hacer {[4] } así que hice esto:

test_spdf <- as(test, "SpatialPixelsDataFrame")
test_df <- as.data.frame(test_spdf)
colnames(test_df) <- c("value", "x", "y")

Y, entonces es solo cuestión de enviar eso + el shapefile a ggplot2:

ggplot() +  
  geom_tile(data=test_df, aes(x=x, y=y, fill=value), alpha=0.8) + 
  geom_polygon(data=OR, aes(x=long, y=lat, group=group), 
               fill=NA, color="grey50", size=0.25) +
  scale_fill_viridis() +
  coord_equal() +
  theme_map() +
  theme(legend.position="bottom") +
  theme(legend.key.width=unit(2, "cm"))

introduzca la descripción de la imagen aquí

Funcionará con cualquier escala de temperatura continua ahora, tho. Viridis es solo uno de los mejores para venir alrededor en un tiempo muy largo.

Puedes usar lo siguiente si tienes que usar gplot:

gplot(test) +  
  geom_tile(aes(x=x, y=y, fill=value), alpha=0.8) + 
  geom_polygon(data=OR, aes(x=long, y=lat, group=group), 
               fill=NA, color="grey50", size=0.25) +
  scale_fill_viridis(na.value="white") +
  coord_equal() +
  theme_map() +
  theme(legend.position="bottom") +
  theme(legend.key.width=unit(2, "cm"))
 24
Author: hrbrmstr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-21 11:09:08

Esta es la solución fácil usando ggplot:

scale_fill_gradientn(colours = terrain.colors(4),limits=c(0,1),  
                 space = "Lab",name=paste("Probability \n"),na.value = NA)

En scale_fill_gradientn (también debería funcionar para scale_file_gradient), establezca na.valor = NA.

 0
Author: Mio_Mio_Mate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-30 11:10:00