在ggplot2中将空图添加到facet_wrap [英] adding empty graphs to facet_wrap in ggplot2

查看:158
本文介绍了在ggplot2中将空图添加到facet_wrap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建3个所有面板应该具有相同大小的图,所以我认为解决方案可能是facet_wrap。我的问题是,我不希望每个

  df < -  data.frame(group = c(1,1,2,2,2,3,3),
name = c('a','b','c','d','e','f', 'g'),
x = c(1,2,3,4,5,6,7),
y = c(2,3,4,5,6,7,8))
ggplot(df,aes(x,y))+ geom_point()+ facet_wrap(〜name,ncol = 3)

结果将这些图形组合成一个连续的顺序,但我希望将它们分组到我的组列。



所以我期望的结果是

  ab _ 
cde
fg _

但我得到的是

  abc 
def
g __

有没有人建议像这样创建一个图表,也许通过添加空图表?我发现了另一个线程的评论和绘图,我创建了第二个解决方案。它使用 gridExtra 并直接操作ggplot grob。我认为它给出了期望的结果,但是以我介绍的形式,这是手动工作。此解决方案使用 facet_wrap 而不是 facet_grid



第一,我为变量 name 添加了一个占位符级别,这将确保创建空面并创建图形:

  df $ name2 < -  factor(df $ name,levels = c('a','b','','c','d' ,'e','f','g',''))
p <-ggplot(df,aes(x,y))+ geom_point()+ facet_wrap(〜name2,ncol = 3,drop = FALSE)

drop = FALSE 是什么导致 ggplot 绘制空的构面。
此图与我的第一个解决方案仅在标记方面有所不同。现在到棘手的部分:

  library(gridExtra)
g < - ggplotGrob(p)
# #删除空面板
g $ grobs [%(c)中的名称(g $ grobs)%(panel3,panel9,strip_t3,strip_t9)]< - NULL
## remove它们来自布局
g $ layout< - g $ layout [!(g $ layout $ name%in%c(panel-3,panel-9,
strip_t-3 ,strip_t-9)),]
##将轴靠近面板
g $ layout [g $ layout $ name ==axis_b-9,c(t,b )] = c(9,9)

基本上这就是评论所说的。如果您使用另一组图,请查看名称(g $ grobs) g $ layout $ name ,找出哪些元素必须被删除。



现在您可以使用

  grid.newpage()
grid.draw(g)



编辑2: $ b

对于较新版本的 ggplot2 ,上述解决方案不起作用。不幸的是,我不知道这个版本是从哪个版本开始的,但它在2.2.1版本中无法使用。



必须修改的部分是grob:

  g < -  ggplotGrob(p)
#获取必须删除的grobs
rm_grobs <-g $ layout $ name%in%c(panel-1-3,panel-3-3,strip-t-3-1,strip-t-3-3 )
#remove grobs
g $ grobs [rm_grobs]< - NULL
g $ layout< - g $ layout [!rm_grobs,]
##将轴移近面板
g $ layout [g $ layout $ name ==axis-b-3-3,c(t,b)] = c(14.5,14.5)
grid.newpage()
grid.draw(g)

主要变化是 g $ grobs 不再是已命名的列表,并且grobs的名称已更改。请注意,面板标记为panel-row-col,而灰色条则为strip-t-col-row




I am trying to create 3 plots where all the panels should have the same size, so I thought the solution might be facet_wrap. My problem is, I do don't want the same number of graphs in each

df <- data.frame(group=c(1,1,2,2,2,3,3),
                 name=c('a','b','c','d','e','f','g'),
                 x=c(1,2,3,4,5,6,7),
                 y=c(2,3,4,5,6,7,8))
ggplot(df, aes(x,y)) + geom_point() + facet_wrap(~ name, ncol=3)

The result combines the graphs into a sequential order but I would like to group them by my group column.

So the result I expect is

a b _
c d e 
f g _

But what I get is

a b c
d e f
g _ _

Has anyone a suggestion to create a graph like this, maybe by adding empty graphs? I found a other thread Force facet_wrap to fill bottom row... But I couldn't get it to run in my case.

解决方案

facet_wrap simply puts one plot after the other and inserts "line breaks" after the appropriate number of plots. But there is also facet_grid that lets you specify a row and a column index. Your row index is group and I now add a column index as follows:

cols<-c(a=1,c=1,f=1,b=2,d=2,g=2,e=3)
df$col <- as.factor(cols[as.character(df$name)])

Now you can plot the facet grid with

ggplot(df, aes(x,y)) + geom_point() + facet_grid(group~col)

Of course, depending on what your problem is, you will have to think of an appropriate way to set the column indices.

This is the plot:

Edit:

In reaction to your comment and drawing from this answer, I created a second solution. It uses gridExtra and manipulates the ggplot grob directly. I think it gives the desired result, but in the form I present it, it is "manual work". This solution uses facet_wrap instead of facet_grid.

First, I add a "place holder levels" to the variable name, which will ensure that the empty facets are created and then create the plot:

df$name2 <- factor(df$name,levels=c('a','b','','c','d','e','f','g',' '))
p <- ggplot(df, aes(x,y)) + geom_point() + facet_wrap(~name2,ncol=3,drop=FALSE)

drop=FALSE is what causes ggplot to draw the empty facets. This plot differs from my first solution only in how the facets are labelled. Now to the tricky part:

library(gridExtra)
g <- ggplotGrob(p)
## remove empty panels
g$grobs[names(g$grobs) %in% c("panel3", "panel9", "strip_t3", "strip_t9")] <- NULL
## remove them from the layout
g$layout <- g$layout[!(g$layout$name %in% c("panel-3", "panel-9", 
                                           "strip_t-3", "strip_t-9")),]
## move axis closer to panel
g$layout[g$layout$name == "axis_b-9", c("t", "b")] = c(9,9)

This does basically what the comments say. If you work with another set of plots, look at the output of names(g$grobs) and g$layout$name to figure out, which elements have to be removed.

Now you can create the plot with

grid.newpage()
grid.draw(g)

Edit 2:

For newer versions of ggplot2 the above solution does not work. Unfortunately, I don't know with which version this started, but it definitely does not work with version 2.2.1.

The part that must be changed is the modification of the grob:

g <- ggplotGrob(p)
# get the grobs that must be removed
rm_grobs <- g$layout$name %in% c("panel-1-3", "panel-3-3", "strip-t-3-1", "strip-t-3-3")
# remove grobs
g$grobs[rm_grobs] <- NULL
g$layout <- g$layout[!rm_grobs, ]
## move axis closer to panel
g$layout[g$layout$name == "axis-b-3-3", c("t", "b")] = c(14.5, 14.5)
grid.newpage()
grid.draw(g)

The main changes are that g$grobs is no longer a named list and that the names of the grobs have changed. Note the panels are labelled as "panel-row-col" while for grey bars it is "strip-t-col-row".

这篇关于在ggplot2中将空图添加到facet_wrap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆