Вопрос по facet-wrap, ggplot2, facet, legend, r – Поместите легенду для каждой сетки facet_wrap в ggplot2

22

У меня есть этот фрейм данных:

        Date Server FileSystem PercentUsed
1  12/1/2011      A          /          60
2   1/2/2012      A       /var          50
3   2/1/2012      A        tmp          90
4  2/10/2012      A        /db          86
5  2/13/2012      A       /app          90
6  12/1/2011      B         C:          67
7   1/2/2012      B         D:          67
8   2/1/2012      B         F:          34
9  2/10/2012      B   /restore          89
10 2/13/2012      B         G:          56
11 12/1/2011      C          /          90
12  1/2/2012      C       /tmp          78
13  2/1/2012      C      /data          67
14 2/10/2012      C   /Storage          34
15 2/13/2012      C  /database          12

dput(x)
structure(list(Date = structure(c(2L, 1L, 3L, 4L, 5L, 2L, 1L, 
3L, 4L, 5L, 2L, 1L, 3L, 4L, 5L), .Label = c("1/2/2012", "12/1/2011", 
"2/1/2012", "2/10/2012", "2/13/2012"), class = "factor"), Server = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), .Label = c("A", 
"B", "C"), class = "factor"), FileSystem = structure(c(1L, 9L, 
14L, 5L, 2L, 10L, 11L, 12L, 6L, 13L, 1L, 8L, 3L, 7L, 4L), .Label = c("/", 
"/app", "/data", "/database", "/db", "/restore", "/Storage", 
"/tmp", "/var", "C:", "D:", "F:", "G:", "tmp"), class = "factor"), 
    PercentUsed = c(60L, 50L, 90L, 86L, 90L, 67L, 67L, 34L, 89L, 
    56L, 90L, 78L, 67L, 34L, 12L)), .Names = c("Date", "Server", 
"FileSystem", "PercentUsed"), class = "data.frame", row.names = c(NA, 
-15L))

Я хотел бы поставить легенду прямо рядом с каждымfacet_wrap сетка, своя:FileSystem

Когда я делаю это, это ставит легенду на стороне сюжета для всехFileSystem, Можно ли поставитьFileSystem принадлежат каждому серверу рядом с каждой сеткой?

ggplot(x, aes(Date, PercentUsed, group=1, colour=FileSystem)) + 
     geom_jitter(size=0.5) + geom_smooth(method="loess", se=T) + 
     facet_wrap(~Server, ncol=1)

Ваш Ответ

3   ответа
23

Лучший способ сделать это сgridExtra пакет:

library(gridExtra)

xs <- split(x,f = x$Server)
p1 <- ggplot(xs$A,aes(x = Date,y = PercentUsed,group = 1,colour = FileSystem)) + 
        geom_jitter(size=0.5) + 
        geom_smooth(method="loess", se=T) + 
        facet_wrap(~Server, ncol=1)

p2 <- p1 %+% xs$B
p3 <- p1 %+% xs$C

grid.arrange(p1,p2,p3)

@joran, как вы можете сделать так, чтобы каждый график в сетке занимал одинаковое пространство, чтобы их галочки совпали? lgd
+1 Спасибо за ваш быстрый ответ. Это такой фантастический способ повторного использования объектов! Legend
Я должен отметить, что вы сделали очень мало очков вgeom_jitter и я'Я не уверен, почему, но я оставил все как есть. Точки есть, но трудно увидеть. joran
@ Legend It 'способ сделать объект ggplot "модульное» в том смысле, что вы можете использовать его, чтобы просто вставить новый фрейм данных, но использовать все те же спецификации geom из предыдущего графика. Конечно, это будет работать только в том случае, если имена столбцов совпадают, и если вы нет использовал любойДругой фреймы данных в других слоях. joran
4

мы могли бы составить список графиков для каждой группы, а затем использоватьcowplot :: plot_grid для построения. У каждого будет этоСобственная легенда:

# make list of plots
ggList <- lapply(split(x, x$Server), function(i) {
  ggplot(i, aes(Date, PercentUsed, group = 1, colour = FileSystem)) + 
    geom_jitter(size = 2) +
    geom_smooth(method = "loess", se = TRUE)})

# plot as grid in 1 columns
cowplot::plot_grid(plotlist = ggList, ncol = 1,
                   align = 'v', labels = levels(x$Server))

Как предложено @Axeman, мы могли бы добавлять метки, используяfacet_grid(~Server), вместо .labels = levels(x$Server)

@ Axeman хорошо о "V"Спасибо, обновил. Я хотел избежать использования фасета, поэтому вместо этого использовал метку. zx8754
Отлично. Если вы хотите, чтобы отображались серые полоски, вы все равно можете добавить+ facet_grid(~Server), С помощьюalign = 'v' вplot_grid даст лучший результат. Axeman
23

Мех, @joran избил меня до этого (мойgridExtra был устаревшим, но мне потребовалось 10 минут, чтобы понять это). Вот'Это аналогичное решение, но это позволяет обрезать кошку по уровням в.Server

library(gridExtra)
out <- by(data = x, INDICES = x$Server, FUN = function(m) {
      m <- droplevels(m)
      m <- ggplot(m, aes(Date, PercentUsed, group=1, colour = FileSystem)) + 
         geom_jitter(size=2) + geom_smooth(method="loess", se=T)
   })
do.call(grid.arrange, out)

# If you want to supply the parameters to grid.arrange
do.call(grid.arrange, c(out, ncol=3))

Очень хорошо. Я не'не понимаю, чтоdroplevels() был метод дляdata.frames. Тот'удобно! Josh O'Brien
На самом деле, я закончил тем, что перенес все легенды на вершину. Я могу'не использовать одну легенду, поскольку они уникальны для сюжета. Хотя было бы неплохо узнать, есть ли способ прописать ширину. mlt
@mlt подумайте над тем, чтобы задать новый вопрос, хотя AFAIKне возможно (этохотя можно определить поля). Roman Luštrik
Есть ли аккуратный способ принудительного выравнивания, то есть, чтобы ширина области графика была одинаковой? Предписать ширину легенды? mlt
@mlt рассмотрите возможность перемещения легенды в верхнюю часть первого рисунка и удалите ее из остальных. Roman Luštrik

Похожие вопросы