ggplot2:在3-way plot中在外侧面板上有公共的facet bar [英] ggplot2: have common facet bar in outer facet panel in 3-way plot

查看:200
本文介绍了ggplot2:在3-way plot中在外侧面板上有公共的facet bar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  label_rev<  -  function(labels,multi_line = TRUE,sep =: ){
label_both(rev(labels),multi_line = multi_line,sep = sep)
}
require(ggplot2)
p < - ggplot(data = mtcars,aes(wt ,mpg))+ geom_point()
p + facet_grid(vs + cyl〜gear,labeller = label_rev)

我看到下图:
,但与保证自己的答案。给定一个在右边空白处具有多个方面的ggplot,该答案提供了一个函数, OverlappingStripLabels(),它从ggplot获取信息以重建带,使标签重叠。它使用 gtable grid 函数来执行此操作。

 库(ggplot2)
库(网格)
库(gtable)
库( plyr)

#初始绘图
绘图= ggplot(数据= mtcars,aes(wt,mpg))+ geom_point()+
facet_grid(vs + cyl〜gear,labeller = label_both)+
theme_bw()+
theme(panel.spacing = unit(.2,lines),
strip.background = element_rect(color =grey30,fill = grey90))


##获得重叠条形标签的函数
OverlappingStripLabels =函数(绘图){

#获取ggplot grob
pg = ggplotGrob(plot)

###从图中收集一些关于条带的信息
#获取条带列表
strip = lapply(grep( strip-r,pg $ layout $ name),function(x){pg $ grobs [[x]]})

#条数
NumberOfStrips = sum(grepl( pattern =strip-r,pg $ layout $ name))

#列数
NumberOfCols = length(strip [[1]])

#面板间距
plot_theme< - function(p){
plyr ::默认值(p $ theme,theme_get())
}
PanelSpacing = plot_theme(plot)$ panel.spacing

#映射新条带的边界
Nlabel = vector(list,NumberOfCols)
map = vector(list,NumberOfCols)
for(i in 1:NumberOfCols){

for(j in 1: NumberOfStrips){
Nlabel [[i]] [j] = getGrob(grid.force(strip [[j]] $ grobs [[i]]),gPath(GRID.text),grep = TRUE )$标签
}

map [[i]] [1] = TRUE
for(j in 2:NumberOfStrips){
map [[i]] [j] = Nlabel [[i]] [j]!= Nlabel [[i]] [j-1]
}
}

##构建gtable来包含新单元
newStrip = gtable(heights = unit.c(rep(unit.c(unit(1,null),PanelSpacing),NumberOfStrips-1),unit(1,null))
widths = strip [[1]] $ widths)

##填充gtable
seqTop = list()
(我在NumberOfCols中:1){
Top = which(map [[i]] == TRUE)
seqTop [[i]] = if(i == NumberOfCols)2 * Top - 1 else sort(unique(c(seqTop [ [i + 1]],2 * (1))
seqBottom = c(seqTop [[i]] [ - 1] -2,(2 * NumberOfStrips-1))
newStrip = gtable_add_grob(newStrip,lapply(strip [ seqTop [[i]] + 1)/ 2],function(x)x [[1]] [[i]]),l = i,t = seqTop [[i]],b = seqBottom)
}

##将条带放入图中
#获取原始条带的位置
pos = subset(pg $ layout,grepl(strip-r, pg $ layout $ name),t:r)

##使用这些来定位新条带
pgNew = gtable_add_grob(pg,newStrip,t = min(pos $ t),l =独特(pos $ l),b = max(pos $ b))

return(pgNew)
}

##绘制图
grid.newpage()
grid.draw(OverlappingStripLabels(plot))


I have the following code:

label_rev <- function(labels, multi_line = TRUE, sep = ": ") {
     label_both(rev(labels), multi_line = multi_line, sep = sep)
  }
require(ggplot2)
p <- ggplot(data = mtcars, aes(wt, mpg)) + geom_point()
p + facet_grid(vs + cyl ~ gear, labeller = label_rev)

I get the following figure:

Here is my dilemma: I would like the outerstrip of vs:0 to be only one panel encompassing the three facets (cyl:4, 6, 8) and the outstrip of vs:1 to be one panel encompassing the three facets (cyl:4, 6, 8).

Is it possible to do this using ggplot2?

Thanks again in advance for any help!

解决方案

Based on this answer, but sufficiently different to warrant an answer of its own. Given a ggplot with multiple facets on the right margin, this answer provides a function, OverlappingStripLabels(), that takes information from the ggplot to reconstruct the strip so that the labels are overlapping. It uses gtable and grid functions to do so.

library(ggplot2)
library(grid)
library(gtable)
library(plyr)

# Initial plot
plot = ggplot(data = mtcars, aes(wt, mpg)) + geom_point() +
   facet_grid(vs + cyl ~ gear, labeller = label_both) + 
   theme_bw() +
   theme(panel.spacing=unit(.2,"lines"),
         strip.background=element_rect(color="grey30", fill="grey90"))


## The function to get overlapping strip labels
OverlappingStripLabels = function(plot) {

# Get the ggplot grob
pg = ggplotGrob(plot)

### Collect some information about the strips from the plot
# Get a list of strips
strip = lapply(grep("strip-r", pg$layout$name), function(x) {pg$grobs[[x]]})

# Number of strips
NumberOfStrips = sum(grepl(pattern = "strip-r", pg$layout$name))

# Number of columns
NumberOfCols = length(strip[[1]])

# Panel spacing
plot_theme <- function(p) {
   plyr::defaults(p$theme, theme_get())
}
PanelSpacing = plot_theme(plot)$panel.spacing

# Map the boundaries of the new strips
Nlabel = vector("list", NumberOfCols)
map = vector("list", NumberOfCols)
for(i in 1:NumberOfCols) {

  for(j in 1:NumberOfStrips) {
   Nlabel[[i]][j] = getGrob(grid.force(strip[[j]]$grobs[[i]]), gPath("GRID.text"), grep = TRUE)$label
  }

map[[i]][1] = TRUE
for(j in 2:NumberOfStrips) {
   map[[i]][j] = Nlabel[[i]][j] != Nlabel[[i]][j-1]
   }
}

## Construct gtable to contain the new strip
newStrip  = gtable(heights = unit.c(rep(unit.c(unit(1, "null"), PanelSpacing), NumberOfStrips-1), unit(1, "null")), 
                   widths = strip[[1]]$widths)

## Populate the gtable  
seqTop = list()
for(i in NumberOfCols:1) {  
   Top = which(map[[i]] == TRUE)
   seqTop[[i]] = if(i == NumberOfCols) 2*Top - 1 else  sort(unique(c(seqTop[[i+1]], 2*Top - 1)))  
   seqBottom = c(seqTop[[i]][-1] -2, (2*NumberOfStrips-1))
   newStrip = gtable_add_grob(newStrip, lapply(strip[(seqTop[[i]]+1)/2], function(x) x[[1]][[i]]), l = i, t = seqTop[[i]], b = seqBottom)
}

## Put the strip into the plot
# Get the locations of the original strips
pos = subset(pg$layout, grepl("strip-r", pg$layout$name), t:r)

## Use these to position the new strip
pgNew = gtable_add_grob(pg, newStrip, t = min(pos$t), l = unique(pos$l), b = max(pos$b))

return(pgNew)
}

## Draw the plot
grid.newpage()
grid.draw(OverlappingStripLabels(plot))

这篇关于ggplot2:在3-way plot中在外侧面板上有公共的facet bar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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