2015-10-20 1 views
18

Je voudrais faire un terrain en utilisant studio R similaire à celui ci-dessous (créé à Arc Map)Comment configurer l'utilisation ggplot2 pour mapper une trame

enter image description here

J'ai essayé le code suivant:

# 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 sortie de ce code ressemble à ceci:

enter image description here

Un couple de choses à noter. Tout d'abord, les shapefiles des bassins versants sont absents de la version R. c'est bon. Deuxièmement, l'arrière-plan gris le plus sombre dans la courbe R est des valeurs sans données. Dans Arc, ils ne s'affichent pas, mais dans R, ils s'affichent avec gplot. Ils ne présentent pas quand j'utilise « complot » du paquet de trame:

plot(test) 

enter image description here

Mes questions sont les suivantes:

  1. Comment puis-je me débarrasser du gris foncé NoData remplir dans l'exemple 'gplot'?
  2. Comment définir la légende (barre de couleurs) pour qu'elle soit raisonnable (comme dans les légendes d'ArcMap et de raster 'plot'?)
  3. Comment contrôler la palette de couleurs?

Pour noter, j'ai essayé beaucoup de versions différentes de

scale_fill_brewer 
scale_fill_manual 
scale_fill_gradient 

et ainsi de suite et ainsi de suite mais je reçois des erreurs, par exemple

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 

Enfin, une fois que j'ai une solution pour tracer une de ces cartes, je voudrais tracer plusieurs cartes sur une figure et créer une seule barre de couleurs pour l'ensemble du panel (ie une barre de couleurs pour toutes les cartes) et je voudrais pouvoir contrôler où se trouve la barre de couleurs et la taille du col orbar. Voici un exemple de ce que je peux faire avec grid.arrange, mais je ne peux pas comprendre comment définir un seul colorbar:

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 

La sortie est la suivante:

enter image description here

Le shapefile et fichier raster sont disponibles à l'adresse suivante:

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

Un grand merci à l'avance.

devtools :: session_info() Informations de session ------------------------------------- -------------------------------------------------- ------------------------------ valeur de réglage
version R version 3.1.1 (2014-07-10) système x86_64, darwin10.8.0
ui rstudio (0.98.1103)
langue (EN)
collationner en_US.UTF-8
tz America/Los_Angeles

paquets --------------- -------------------------------------------------- -------------------------------------------------- ------ package * version date source
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) digest 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) treillis * 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) MASS 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) échelles * 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 20.06.2013 3,98 à 1,1 CRAN (R 3.1.0) zoo 27/02/2014 1,7 à 11 CRAN (R 3.1.0)

+2

ce qui est la raison pour laquelle vous souhaitez utiliser pour cette ggplot? – RobertH

+1

@RobertH Je ne m'engage pas à utiliser ggplot mais en général j'aime ggplot et j'essaie de l'apprendre donc j'aimerais pouvoir produire des complots avec ggplot efficacement. N'hésitez pas à partager d'autres solutions. Je vous remercie. –

+0

@hrbrmstr s'il vous plaît identifier ce qui ne fonctionne pas. Peut-être que vous vous battez avec le fait que j'ai inclus des chemins absolus qui ne fonctionneront évidemment pas sur la machine de quelqu'un d'autre. J'ai inclus un lien vers les données réelles à la fin de mon message. Si vous placez les données dans un dossier et remplacez les chemins avec le chemin d'accès à votre dossier, cela devrait fonctionner. Je ne suis pas assez compétent avec R pour générer les données à partir de zéro. –

Répondre

9

Voilà comment je le ferais, avec rasterVis::levelplot:

choses de charge:

Lire choses:

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

Définir une palette de rampes de couleurs (ou un vecteur de couleurs d'une longueur 1 plus courte que le nombre de sauts pour la rampe de couleurs définie avec l'argument at ci-dessous).

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

choses Terrain:

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 

enter image description here

Vous pourriez vraiment vouloir les grandes lignes de la légende (y compris les tiques) tracée, auquel cas ajouter axis.line=list(col='black') à la liste des colorkey args. Cela est nécessaire pour passer outre la suppression générale des boîtes causées par 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))     

enter image description here

Je suis d'accord avec @hrbrmstr que viridis est souvent un better ramp to use, en dépit d'être - à mon avis - un peu laid . Les principaux avantages sur quelque chose comme ColorBrewer RdYlBu sont que les couleurs sont encore distinctes lorsqu'elles sont désaturées, et les différences de couleur reflètent mieux les différences de valeurs. Je crois que RdYlBu est parfaitement accessible pour Deuteranopia/Protanopia/Tritanopia couleur-cécité, cependant.

est ici la version 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)) 

enter image description here


EDIT

En réponse à la question supplémentaire de l'OP, voici comment tracer plusieurs rasters comme l'a demandé.

En supposant que tous les rasters ont la même étendue, résolution, projections, etc., vous pouvez les empiler dans un RasterStack, puis utiliser levelplot sur la pile. Vous pouvez passer width comme un élément de la liste passée à colorkey pour contrôler la hauteur de la légende ("width" est un peu contre-intuitif, mais par défaut les légendes sont verticales). Si vous souhaitez supprimer les étiquettes de bande au-dessus de chaque panneau (comme je l'ai fait ci-dessous - par défaut, elles portent les noms de couches de la pile [names(s)]), vous pouvez ajouter strip.border et strip.background à la liste passée à 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)) 

enter image description here

+0

J'aime vraiment la solution levelplot, même si ma question était spécifique à l'utilisation de ggplot et/ou de gplot. Pouvez-vous éditer votre solution pour montrer comment je peux tracer quatre de ces cartes de température dans un sous-champ avec une seule barre de couleur en bas et contrôler les dimensions de la barre de couleurs pour que la barre de couleur ne soit pas aussi haute ? J'ajoute un exemple de ce que j'ai fait en utilisant grid.arrange à mon post original en combinaison avec votre solution mais vous verrez qu'il y a des colorbars pour chaque figure. –

+1

Une autre solution pour supprimer les rectangles des labels consiste à utiliser la fonction 'rasterTheme':' myTheme <- rasterTheme (region = viridis (n = 9)); myTheme $ axis.list $ col <- 'transparent''. Ensuite, vous utilisez 'par.settings = myTheme' dans l'appel' levelplot'. –

15
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") 

Vous avez pas inclus tout ce que vous utilisiez pour faire test si je l'ai fait:

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

Et, il est juste une question d'envoyer que + le shapefile à 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")) 

enter image description here

Il fonctionnera avec n'importe quelle échelle de température continue maintenant, tho. Viridis est juste l'un des meilleurs à venir dans un très long moment.

Vous pouvez utiliser ce qui suit si vous devez utiliser 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")) 
+0

aucune de ces solutions ne fonctionne pour moi. Pour la première solution, j'obtiens l'erreur que "ggplot2 ne sait pas comment traiter les données de la classe RasterLayer", et pour la solution 2, j'obtiens une erreur pour le theme_map "Erreur: object 'theme_map' introuvable". J'ai chargé "ggthemes" –

+0

c'est super facile de le faire dans les champs de commentaires SO (je le fais de façon frustrante tout le temps). ajoutez une 'library (ggthemes)' pour le second numéro (je mettrai à jour le post). pour le premier, j'ai transformé votre objet 'test' différemment. – hrbrmstr

+0

effectivement, j'avais 'library (ggthemes)' dans le post, vous devez faire cela pour 'theme_map' – hrbrmstr