如何使用 ggplot 去除空的分面?

3
我正在使用 ggplot 的 facet_grid 来制作 geom_point,但是我得到了一个空的 facet,我不知道如何删除它们或者如何结构化我的数据以避免出现空的 facet?
这是我的数据示例:
data = data.frame(
  F1=c(0.69, 0.59, 0.6 , 0.52, 0.56, 0.58, 0.52, 0.53, 0.41, 0.57,
       0.54, 0.38, 0.48, 0.31, 0.35,
       0.43, 0.36, 0.38, 0.23, 0.48, 0.55, 0.48, 0.49, 0.46, 0.49,
       0.52, 0.48, 0.48, 0.35, 0.5 ,
       0.51, 0.58, 0.51, 0.59, 0.51, 0.57, 0.5 , 0.59, 0.47, 0.51,
       0.61, 0.58, 0.61, 0.59, 0.61, 0.67, 0.6 , 0.59, 0.47, 0.61,
       0.61, 0.52, 0.53, 0.60,0.62, 0.53, 0.62, 0.63, 0.24, 0.38),
  F2 = c(0.01, 0.01, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01,
         0.42, 0.35, 0.43, 0.31, 0.34, 0.41, 0.34, 0.34, 0.42, 0.39, 0.44, 0.43,
         0.49, 0.43, 0.42, 0.53, 0.41, 0.42, 0.50, 0.40 ,
         0.53, 0.58, 0.57, 0.55, 0.51, 0.65, 0.51, 0.52, 0.62, 0.49,
         0.63, 0.68, 0.67, 0.66, 0.61, 0.66, 0.61, 0.62, 0.62, 0.49,
         0.84, 0.65, 0.69, 0.56, 0.72, 0.61, 0.73, 0.68, 0.72, 0.72),
  s1= c(rep(c("a"),10),
        rep(c("b"),10),
        rep(c("c"),10),
        rep(c("d"),10),
        rep(c("f"),10),
        rep(c("g"),10)),
  s2= c(rep(c("g1"),20),
        rep(c("g2"),40)),
  M=rep(c("M1",
          "M2",  
          "M3",    
          "M4",    
          "M5",   
          "M6",         
          "M7", 
          "M8",
          "M9",
          "M10"),6))

我的代码:
ggplot (data, aes (x = F1, y = F2, shape = M)) +
  facet_grid(s2 ~ s1) + scale_shape_manual(values=c(7,13,23,0,8,1,15,2,17,3,25))+
  geom_point () 

我明白了:

enter image description here

预期情节: 在此输入图片描述

2
使用 facet_wrap - A. Suliman
当然我尝试了 facet_wrap(s2 ~ s1),但它并没有给我想要的结果! - Ph.D.Student
我尝试了你的代码,但是右侧的附加文本并未显示。此外,我想要将同一行中仅保留两个facets并将额外的文本放置在右侧。 - Ph.D.Student
这篇关于移除grobs的帖子可能会帮助您移除空面板,但您可能想要移动剩余的面板。或者,您可以使用一些子集和包grid.extra来产生每个单独的图,并在同一页上绘制结果图。 - Hobo Sheep
5个回答

5
我不知道为什么facet_wrap不能起作用。
下面的代码可以产生你想要的结果。
p <- ggplot (data, aes (x = F1, y = F2, shape = M))
p <- p + geom_point () 
p <- p +  facet_wrap(s2 ~ s1,ncol=2) + scale_shape_manual(values=c(7,13,23,0,8,1,15,2,17,3,25))
p

谢谢您的建议,您的代码将文本g1和g2添加到了顶部,而我希望根据我在帖子中指示的照片,文本g1和g2位于右侧 - Ph.D.Student
如果你真的想要展示你所展示的内容,@Axeman的解决方案可能更好。否则,在facet_wrap调用中使用“labeller = label_wrap_gen(multi_line=FALSE)”参数可以节省空间。 - Boidot
谢谢您的解决方案,但我仍在尝试使用函数:gtable_add_colsgtable_add_grob来获取我的绘图。 - Ph.D.Student

2
如果您确实需要创建带有双侧标签的示例输出,您需要创建三个图,例如:

如果您真正需要创建这样的示例输出,需要创建三个绘图,类似于:

p3 <- ggplot(subset(data, s1 %in% c('f', 'g')), aes(F1, F2, shape = M)) + 
  geom_point() + 
  facet_grid(s2 ~ s1) +
  scale_shape_manual(values = c(7,13,23,0,8,1,15,2,17,3,25))
p1 <- p3 %+% subset(data, s1 %in% c('a', 'b')) +
  theme(axis.text.x = element_blank(), axis.ticks.x = element_blank(), 
        axis.title.x = element_blank(), legend.position = 'none')
p2 <- p1 %+% subset(data, s1 %in% c('c', 'd'))

cowplot::plot_grid(p1, p2, p3, nrow = 3, align = 'v', axis = 'lr', rel_heights = c(1, 1, 1.2))

但我通常会选择@Boidot提供的更简单的包装解决方案。


我似乎无法附加图片,imgur似乎出现了问题。 - Axeman
是否可以为y轴设置一个单一的标题? - Ph.D.Student
我发现使用函数 gtable_add_cols、gtable_add_grob 可以绘制图表,但是我在添加列的大小方面遇到了问题链接 - Ph.D.Student

2

我找到了一个解决方案来回答我的问题,现在我想和大家分享一下:

p <- qplot(data=data, x=F1, y=F2)+facet_wrap( ~ s1,ncol = 2)
z <- ggplotGrob(p)
gtable_show_layout(z)
z <- gtable_add_cols(z, unit(0.08, 'null'), 11)
gtable_show_layout(z)
z <- gtable_add_grob(z,
                     list(rectGrob(gp = gpar(col=NA, fill = gray(0.85), size = 0.5,face="bold")),  
                          textGrob("g1", 
                                   rot = -90, gp = gpar(col = gray(0),fontsize=12,fontface = 'bold'))),
                     7, 12,9,12, name = paste(runif(2)))
gtable_show_layout(z)
z <- gtable_add_grob(z,
                     list(rectGrob(gp = gpar(col=NA, fill = gray(0.85), size = 0.5,face="bold")),  
                          textGrob("g2", 
                                   rot = -90, gp = gpar(col = gray(0),fontsize=12,fontface = 'bold'))),
                     12, 12,18,12, name = paste(runif(2)))

z <- gtable_add_cols(z, unit(1/6, "line"),11)
grid.newpage()
grid.draw(z)

这就是我想要的图表

我希望我的解决方案对其他人有用!


1
另一个选择是使用 ggh4x 包,结合 facet_manual 函数,根据 s1 和 s2 列创建自定义设计布局,如下所示:
library(ggplot2)
library(ggh4x)

design = "
AB
CD
EF"

ggplot (data, aes (x = F1, y = F2, shape = M)) +
  scale_shape_manual(values=c(7,13,23,0,8,1,15,2,17,3,25))+
  geom_point() +
  ggh4x::facet_manual(vars(s1,s2), design = design)

使用reprex v2.0.2于2023年4月28日创建


1
这应该是被接受的答案。ggh4x包使得这个之前令人望而却步的任务变得非常简单。 - undefined

0

这种方法怎么样?

data %>% 
  ggplot(aes(F1, F2, shape = M, color = s2)) +
  geom_point() +
  facet_grid(~ s1) + 
  scale_shape_manual(values=c(7,13,23,0,8,1,15,2,17,3,25))

图表是:


我在filter_impl(.data, quo)中发现了这个错误:结果的长度必须为4,而不是60!我正在尝试使用qplot(data=data, x=F1, y=F2)+facet_wrap( ~ s1,ncol = 2)并添加列与gtable_add_cols...但我还没有成功!!!谢谢你帮助我...如果你知道我如何使用这些函数... - Ph.D.Student
抱歉,我使用了错误的数据集,你需要将“df”替换为“data”。我已经修改了我的回答。希望能有所帮助。 - Stephan
抱歉,@Axeman,但那基本上是错误的。我在我的答案中添加了图片。我建议您先检查输出。 - Stephan
你的图表也不需要两个 geom_point 层。只需要 ggplot(data, aes(F1, F2, shape = M, color = s2)) + geom_point() + ... 就可以了。 - Axeman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接