R 在ggplot2中为每个镶嵌面_包裹栅格放置图例

R 在ggplot2中为每个镶嵌面_包裹栅格放置图例,r,ggplot2,legend,facet,facet-wrap,R,Ggplot2,Legend,Facet,Facet Wrap,我有这个数据框: 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

我有这个数据框:

        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\u wrap
网格旁边放一个图例,它有自己的
文件系统

当我这样做时,它会将所有
文件系统的图例放在绘图的一侧。是否可以将
文件系统
放在每个网格旁边的每个服务器上

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)

最好的方法是使用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)
库(gridExtra)
xsMeh,@joran击败了我(我的
gridExtra
已经过时,但我花了10分钟才意识到)。这里有一个类似的解决方案,但是这个解决方案在
服务器中按级别对猫进行一般性剥皮

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))
库(gridExtra)

out我们可以为每组绘制一个图列表,而不是使用facet,然后使用cowplot::plot_网格进行绘制。每个人都有自己的传奇:

# 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))
#制作绘图列表

ggList我喜欢@joran的答案,并根据他们的代码提供了一些选项作为起点这两个选项都解决了面对齐错误的问题。

刻面外的图例 如果为图例项选择单间距字体,则可以使用
str_pad
在所有图例项的右侧添加填充,强制每个图例项的长度保持一致

如果您愿意使用单间距字体,这是一个快速解决方案

library(ggplot2)
library(dplyr)
library(gridExtra)
library(stringr)

l <- max(nchar(as.character(x$FileSystem)))
mylevels <- as.character(levels(x$FileSystem))
mylevels <- str_pad(mylevels, width = l, side = "right", pad = " ")
x <- mutate(x, FileSystem = factor(str_pad(FileSystem, width = l, side = "right", pad = " "),
            levels = mylevels))
windowsFonts("Lucida Sans Typewriter" = windowsFont("Lucida Sans Typewriter"))
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) +
  theme(legend.text = element_text(family = "Lucida Sans Typewriter"))

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

grid.arrange(p1,p2,p3)

除了
gridExtra
cowplot
之外,现在游戏中还有
补丁。因此,您可以执行以下操作:

require(ggplot2)
需要(拼凑)
#分裂
dfs=split(df,f=df$Server)
#应用ggplot函数并写入列表
gg_l=lappy(dfs,函数(x){
ggplot(x,aes(x=日期,y=使用百分比,组=1,颜色=文件系统))+
几何抖动(大小=0.5)+
geom_光滑(方法=“黄土”,se=TRUE)+
facet_wrap(~Server,ncol=1)
})
#拼凑
包裹图(gg\U l,ncol=1)


您也可以手动组合绘图,请查看。我将OP的数据用于
df

我应该注意到,您在
geom_jitter
中使点非常小,我不确定为什么,但我保留了它。要点就在这里,但很难看出。我对
%+%
运算符有点感兴趣。您能解释一下它的功能吗?@Legend这是一种使ggplot对象“模块化”的方法,即您可以使用它简单地插入一个新的数据帧,但使用以前绘图中所有相同的geom规范。当然,只有当列名都匹配,并且您没有在其他层中使用任何其他数据帧时,它才会起作用。+1感谢您的及时回复。这是一种非常好的重新使用对象的方式@乔兰:你怎么能使网格中的每个绘图占用相等的空间,使它们的x记号对齐?非常好。我没有意识到
droplevels()
有一个
data.frame
s的方法。那很方便!是否有一种简洁的方法来强制对齐,即保持绘图区域宽度不变?指定图例宽度?@ MLT考虑将图例移到第一个图的顶部,并将其从其余部分中删除。实际上,我最终把所有的传奇故事移到了顶部。我不能使用单个图例,因为它们在每个绘图中都是唯一的。尽管知道是否有办法规定宽度是很好的。@ MLT考虑提出一个新的问题,尽管如此,这是不可能的(但是有可能定义边缘)。如果希望显示灰色镶嵌条,仍然可以添加
+facet\u网格(~Server)
。在
plot\u grid
中使用
align='v'
将获得更好的外观效果。@Axeman关于“v”的观点很好,谢谢,已更新。我想避免使用facet,所以改用label。
library(lubridate)
x <- mutate(x, Date = as.Date(as.character(Date), format = "%m/%d/%Y"))
xs <- split(x,f = x$Server)
p1 <- ggplot(xs$A,aes(x = Date,y = PercentUsed,group = 1,colour = FileSystem)) + 
  geom_jitter(size=0.5) + 
  scale_x_date(expand = expansion(add = c(5, 20)),
               date_labels = "%d-%m-%Y") +
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~Server, ncol=1) +
  theme_bw() +
  theme(legend.position = c(0.9, 0.5))

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

grid.arrange(p1,p2,p3)