Différentes légendes et de remplissage pour ggplot? Facettée
Question
Désolé de ne pas inclure les données d'exemple pour mon problème. Je ne pouvais pas trouver un moyen de produire facilement un fichier de forme par exemple. Si tout va bien, les utilisateurs expérimentés de ggplot
peuvent voir ce que je voudrais faire de la description ci-dessous.
J'ai:
-
A
data.frame
X avec des informations sur des parcelles d'échantillonnage (plotid
,var1
,var2
,var3
,var4
, ...) -
Un fichier de forme de polygone
Y
avec l'information spatiale pour les parcelles d'échantillonnage
Importation du fichier de formes Y
(avec maptools
) et fortify
ing comme data.frame
Z
(ggplot2
) fonctionne très bien. melt
ing X
à X_melted
fonctionne tout aussi bien. merge
-ing Z
et X_melted
à mapdf
fonctionne aussi bien.
Cela signifie que nous avons maintenant une data.frame
en forme longue avec des informations spatiales et var1
, var2
, var3
, ...
Maintenant, je veux tracer cette trame de données comme ceci:
pl1 <- ggplot(mapdf,aes(long,lat),group=group)
pl1 <- pl1 + geom_polygon(aes(group=group,fill=value),colour="black")
pl1 <- pl1 + facet_grid(variable ~ .)
pl1 <- pl1 + coord_equal(ratio = 1)
pl1
Le résultat est un beau terrain avec un panneau pour chaque variable. Les cartes des panneaux sont identiques, mais la couleur de remplissage varie selon les valeurs des variables. Jusqu'à présent, tout fonctionne comme un charme ... avec un problème:
Les variables ont différentes valeurs min et max. Par exemple var1
va de 0
à 5
, var2
de 0
à 400
, var3
de 5
à 10
, etc. Dans cet exemple, la légende de la couleur de remplissage passe de 0
à 400
. var2
est bien dessiné, mais var1
et var3
sont essentiellement de la même couleur.
Est-il possible que je pourrais utiliser une autre légende pour chaque panneau de la facette? Ou est-ce tout simplement pas (encore) possible avec facet_wrap
ou facet_grid
dans ggplot
?
Je pourrais faire des parcelles individuelles pour chaque variable et les joindre à viewports, mais il a beaucoup de variables et ce serait beaucoup de travail.
Ou bien est-il peut-être un autre paquet ou méthode que je pourrais utiliser pour accomplir ce que je voudrais faire?
aide serait très apprécié. :)
Edit:
Avec l'aide de la description ggplot2
-paquet, je construisais un exemple qui illustre mon problème:
ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3"))
values <- data.frame(
id = ids,
val1 = cumsum(runif(6, max = 0.5)),
val2 = cumsum(runif(6, max = 50))
)
positions <- data.frame(
id = rep(ids, each = 4),
x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3,
0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3),
y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5,
2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2)
)
values <- melt(values)
datapoly <- merge(values, positions, by=c("id"))
p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black")
p <- p + facet_wrap(~ variable)
p
Le panneau de droite montre des valeurs différentes pour var2
sur la carte. Sur le panneau de gauche cependant, tous les polygones ont la même couleur. Ce qui est logique, car on utilise un seul gradient de couleur pour tous les panneaux. Puis-je utiliser un dégradé de couleurs différentes pour chaque panneau?
La solution
À l'heure actuelle il ne peut y avoir qu'une seule échelle par parcelle (pour tout sauf x et y).
Autres conseils
Avec le bien de grille
align.plots <- function(..., vertical=TRUE){
#http://ggextra.googlecode.com/svn/trunk/R/align.r
dots <- list(...)
dots <- lapply(dots, ggplotGrob)
ytitles <- lapply(dots, function(.g) editGrob(getGrob(.g,"axis.title.y.text",grep=TRUE), vp=NULL))
ylabels <- lapply(dots, function(.g) editGrob(getGrob(.g,"axis.text.y.text",grep=TRUE), vp=NULL))
legends <- lapply(dots, function(.g) if(!is.null(.g$children$legends))
editGrob(.g$children$legends, vp=NULL) else ggplot2:::.zeroGrob)
gl <- grid.layout(nrow=length(dots))
vp <- viewport(layout=gl)
pushViewport(vp)
widths.left <- mapply(`+`, e1=lapply(ytitles, grobWidth),
e2= lapply(ylabels, grobWidth), SIMPLIFY=F)
widths.right <- lapply(legends, function(g) grobWidth(g) + if(is.zero(g)) unit(0, "lines") else unit(0.5, "lines")) # safe margin recently added to ggplot2
widths.left.max <- max(do.call(unit.c, widths.left))
widths.right.max <- max(do.call(unit.c, widths.right))
for(ii in seq_along(dots)){
pushViewport(viewport(layout.pos.row=ii))
pushViewport(viewport(x=unit(0, "npc") + widths.left.max - widths.left[[ii]],
width=unit(1, "npc") - widths.left.max + widths.left[[ii]] -
widths.right.max + widths.right[[ii]],
just="left"))
grid.draw(dots[[ii]])
upViewport(2)
}
}
p <- ggplot(datapoly[datapoly$variable=="val1",], aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black")
p1 <- ggplot(datapoly[datapoly$variable=="val2",], aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black")
align.plots( p,p1)
Au risque d'énoncer une évidence, il semble que vous devriez être colorez par des valeurs au lieu Percents premières. Ensuite, vos valeurs transformées et votre légende vont de 0 à 1.
Peut-être un peu peu orthodoxe, mais vous pouvez essayer d'affacturage votre « valeur ». Par exemple:
p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=factor(value), group=id),colour="black")
p <- p + facet_wrap(~ variable)
p
ggplot2 utilise des facteurs pour créer des légendes. Donc, si vous pouvez ajouter une colonne qui prend « valeur » et il se casse dans des plages affacturées, vous pouvez remplacer « valeur » avec les gammes.
Créer une colonne, comme "f":
id variable value x y f
1 1.1 val1 0.09838607 2.0 -0.5 0.09-0.13
2 1.1 val1 0.09838607 1.0 0.0 0.09-0.13
3 1.1 val1 0.09838607 1.1 1.0 0.09-0.13
4 1.1 val1 0.09838607 2.2 0.5 0.09-0.13
25 2.1 val1 0.13121347 1.0 0.0 0.13-0.20
...
Ensuite, utilisez:
p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=f, group=id),colour="black")
p <- p + facet_wrap(~ variable)
p
Il faudrait préciser les catégories que vous voulez, ce qui pourrait prendre du temps. Mais au moins le graphique viendrait comment vous le souhaitez. Fondamentalement, vous seriez recodage les données dans une autre colonne. Voici quelques exemples: