2017-02-16 1 views
0

J'essaye de dessiner plusieurs cartes du paquet tmap en utilisant tm_shape() et tm_layout() dans une page en utilisant grid.layout() du paquet grid. Je voudrais tracer une seule légende commune pour toutes les cartes, comme dans l'exemple montré ici:Dessiner plusieurs objets de la classe tmap avec une seule légende commune

ggplot separate legend and plot

Malheureusement, tmap ne fournit pas un ggplot objet. Est-ce que quelqu'un sait comment faire la même chose avec tmaps? Voici un exemple reproductible:

data(World, rivers, metro) 

# creating two separate maps 
africa <- World[[email protected]$continent=='Africa',] 
asia <- World[[email protected]$continent=='Asia',] 

my.breaks <- seq(0,80,20) 

africa.map <- tm_shape(africa) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_layout(bg.color = "white", legend.text.size = 1.3, legend.width = 0.6, 
      legend.outside=TRUE, legend.outside.position = 'top', 
      legend.outside.size = .1, legend.position = c(0.8, 0.2)) 

asia.map <- tm_shape(asia) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_layout(bg.color = "white", legend.text.size = 1.3, legend.width = 0.6, 
      legend.outside=TRUE, legend.outside.position = 'top', 
      legend.outside.size = .1, legend.position = c(0.8, 0.2)) 

page.layout <- grid.layout(nrow = 8, ncol = 5, 
          widths = unit(c(1), "null"), 
          heights = unit(c(1), "null"), 
          default.units = "null", 
          respect = FALSE, 
          just = "centre") 

grid.newpage() 
pushViewport(viewport(layout = page.layout)) 
grid.text(paste('Happy Planet Index'), 
      vp = viewport(layout.pos.row = 1, layout.pos.col = 1:5),gp=gpar(fontsize=20)) 

grid.text('Africa', vp = viewport(layout.pos.row = 2, layout.pos.col = 1:2),gp=gpar(fontsize=20)) 
print(africa.map, vp=viewport(layout.pos.row = 3:6, layout.pos.col = 1:2)) 

grid.text('Asia', vp = viewport(layout.pos.row = 2, layout.pos.col = 3:5),gp=gpar(fontsize=20)) 
print(asia.map, vp=viewport(layout.pos.row = 3:6, layout.pos.col = 3:5)) 

Best, Erich

+0

C'est certainement possible. Pourriez-vous poster un exemple reproductible de ce que vous voulez accomplir? –

+0

Merci Martijn! J'ai ajouté un exemple. Ce que je veux faire est de dessiner seulement une légende commune pour les deux cartes, mieux en séparant la légende de la carte et en la traçant séparément n'importe où dans la zone de traçage comme dans l'exemple de ggplot2. Mais je suis content si vous avez une meilleure solution. – Erich

Répondre

1

Je ne sais pas si cela est ce que vous entendez:

data(World) 

tm_shape(World) + 
    tm_polygons(c("economy", "HPI")) + 
    tm_layout(legend.outside = TRUE) 

La légende commune est tracée en dehors des cartes. Puisque les deux cartes ont des légendes différentes, seule la légende de la première carte est prise.

Vous pouvez également utiliser grid.layout. Dans ce cas, vous devrez imprimer des cartes tmap dans les fenêtres de la grille (voir print.tmap), et la légende dans une autre.

MISE À JOUR:

Pour être complet: normalement, il devrait y avoir un moyen de le faire avec les facettes:

data(World) 
AfAs <- World[[email protected]$continent %in% c('Africa', 'Asia'),] 
tm_shape(AfAs) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_facets(by = "continent", drop.units = TRUE, free.coords = TRUE) 

Si vous devez tracer deux appels tMap, il est plus pratique de processus la légende comme une carte séparée, avec legend.only=TRUE:

africa.map <- tm_shape(africa) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_layout(legend.show = FALSE) 

asia.map <- tm_shape(asia) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_layout(legend.show = FALSE) 

legend.map <- tm_shape(africa) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_layout(legend.only = TRUE) 

grid.newpage() 
page.layout <- grid.layout(nrow = 2, ncol = 2, widths=c(.4,.6), heights=c(.6,.4)) 
pushViewport(viewport(layout = page.layout)) 

print(africa.map, vp=viewport(layout.pos.row = 1:2, layout.pos.col = 1)) 
print(asia.map, vp=viewport(layout.pos.row = 1, layout.pos.col = 2)) 
print(legend.map, vp=viewport(layout.pos.row = 2, layout.pos.col = 2)) 

UPDATE 2

La légende peut être agrandie avec ce code:

legend.map <- tm_shape(africa) + 
    tm_fill("HPI",style = 'fixed',breaks = my.breaks) + 
    tm_layout(legend.only = TRUE, design.mode=TRUE, scale=2, asp=0) 

design.mode=TRUE est à portée de main lors de la conception d'une carte. J'ai dû mettre asp à 0, car il a fallu le rapport d'aspect de l'Afrique: c'est une erreur, puisque le ratio d'aspect devrait suivre le device/viewport lorsque legend.only = TRUE. Ceci est corrigé dans la version devel.

+0

Merci beaucoup! C'est exactement ce que je cherchais. – Erich

+0

Mais maintenant, comment faites-vous que cette légende soit plus grande dans le monde? J'ai essayé toutes les commandes disponibles dans le livre: – Erich

+0

Voir la mise à jour deux. –