несколько графиков на одном холсте, используя ggplot2 - PullRequest
31 голосов
/ 08 марта 2011

Я пытаюсь объединить два графика ggplot2 в один на основе этой таблицы:

   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

Я хочу построить два графика рассеяния со средним значением рейтингов по оси Y и типом по оси X.

Вот как я создаю каждый график:

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

Поскольку p1 и p2 имеют одинаковую ось x, я бы хотел, чтобы они располагались вертикально. Я посмотрел на facet_align, но не смог найти что-то, что могло бы сделать эту работу.

Ответы [ 3 ]

46 голосов
/ 08 марта 2011

Вы можете использовать grid.arrange() в пакете gridExtra следующим образом:

grid.arrange(p1, p2)
14 голосов
/ 08 марта 2011

Julio,

Вы упоминаете, что p1 и p2 имеют одну и ту же ось X, но переупорядочение, которое вы делаете на основе среднего, не делает их одинаковыми. Ось p1 идет «один -> два -> три», а ось p2 - «два -> один -> три». Это намеренно?

Несмотря на это, ggplot предлагает несколько других решений для объединения этих графиков в один, а именно colour и faceting (что вы, возможно, уже пробовали?). Первым шагом к любому из них является melt ваш data.frame в длинном формате. Мы идентифицируем переменную id «Тип», и melt предполагает, что остальные столбцы должны быть melted.

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

Быстрая проверка структуры нового объекта показывает, что почти все в строке, за исключением того, что уровни для типа немного не в порядке:

> 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 ...

Итак, давайте изменим уровни:

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

Теперь для прорисовки. С цветом:

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

или с гранями:

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

Примечание. Я использовал аргумент scales = "free" в огранке, чтобы каждый график имел свой собственный масштаб. Просто удалите этот аргумент, если это не тот эффект, который вам нужен.

8 голосов
/ 21 июня 2014

это старый вопрос, но я недавно нашел функцию multiplot, с которой очень хорошо справляется со своей работой.

Функция multiplot из Кулинарная книга для R:

Сама функция:

# 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))
    }
  }
}

Вам нужно просто получить эту функциюк вашему сценарию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...