web-dev-qa-db-fra.com

plusieurs graphiques dans un canevas à l'aide de ggplot2

J'essaie de fusionner deux tracés ggplot2 en un seul basé sur ce tableau:

   Type    RatingA  RatingB
1  One     3        36
2  Two     5        53
3  One     5        57
4  One     7        74
5  Three   4        38
6  Three   8        83

Je veux faire deux diagrammes de dispersion avec la moyenne des notes sur l'axe y et taper sur l'axe x.

Voici comment je crée chaque graphique:

p1 <- ggplot(test, aes(x=reorder(Type, RatingA, mean), y=RatingA)) +
        stat_summary(fun.y="mean", geom="point")

p2 <- ggplot(test, aes(x=reorder(Type, RatingB, mean), y=RatingB)) + 
        stat_summary(fun.y="mean", geom="point")

Puisque p1 et p2 ont le même axe x, je voudrais qu'ils soient ordonnés verticalement. J'ai regardé facet_align mais je n'ai pas pu trouver quelque chose qui ferait l'affaire.

31
Julio Diaz

Vous pouvez utiliser grid.arrange() dans le package gridExtra comme ceci:

grid.arrange(p1, p2)
46
Ista

Julio,

Vous mentionnez que p1 et p2 ont le même axe x, mais le réordonnancement que vous effectuez en fonction de la moyenne ne les rend pas identiques. L'axe de p1 Va "un -> deux -> trois" tandis que l'axe de p2 Va "deux -> un -> trois". Est-ce intentionnel?

Quoi qu'il en soit, ggplot propose quelques autres solutions pour combiner ces tracés en un seul, à savoir colour et faceting (que vous avez peut-être déjà essayé?). La première étape de l'une ou l'autre de ces étapes consiste à melt votre data.frame au format long. Nous allons identifier la variable id "Type" et melt suppose que le reste des colonnes doit être melted.

test.m <- melt(test, id.var = "Type")

Une vérification rapide de la structure du nouvel objet indique que tout est en ligne, sauf que les niveaux de type sont un peu hors de propos:

> str(test.m)
'data.frame':   12 obs. of  3 variables:
 $ Type    : Factor w/ 3 levels "One","Three",..: 1 3 1 1 2 2 1 3 1 1 ...
 $ variable: Factor w/ 2 levels "RatingA","RatingB": 1 1 1 1 1 1 2 2 2 2 ...
 $ value   : int  3 5 5 7 4 8 36 53 57 74 ...

Alors réarrangons les niveaux:

test.m$Type <- factor(test.m$Type, c("One", "Three", "Two"), c("One", "Two", "Three"))

Maintenant pour le complot. Avec couleur:

ggplot(test.m, aes(x = Type, y = value, group = variable, colour = variable)) + 
stat_summary(fun.y = "mean", geom = "point") 

ou à facettes:

ggplot(test.m, aes(x = Type, y = value, group = variable)) + 
stat_summary(fun.y = "mean", geom = "point") +
facet_grid(variable ~ ., scales = "free")

Remarque J'ai utilisé l'argument scales = "free" Dans le facettage pour que chaque tracé ait sa propre échelle. Supprimez simplement cet argument si ce n'est pas l'effet souhaité.

14
Chase

c'est une vieille question, mais j'ai récemment trouvé la fonction multiplot, avec faire son travail très bien.

La fonction multiplot provient de Cookbook for R:

La fonction elle-même est:

# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols:   Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  require(grid)

  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)

  numPlots = length(plots)

  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel
    # ncol: Number of columns of plots
    # nrow: Number of rows needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                    ncol = cols, nrow = ceiling(numPlots/cols))
  }

 if (numPlots==1) {
    print(plots[[1]])

  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))

      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                      layout.pos.col = matchidx$col))
    }
  }
}

Vous avez juste besoin de source cette fonction dans votre script.

8
AndriusZ