在不翻转facet_grid轴的情况下将strip.y用作strip.x

时间:2018-09-22 15:58:16

标签: r ggplot2

使用代码

library(ggplot2)
library(dplyr)

mydata = tribble(
  ~x, ~y, ~data, ~more,
  0, 50, 'iris', 'this', 
  10, 100, 'iris', 'this',
  0, 50, 'iris', 'that', 
  10, 100, 'iris', 'that',
  0, 0, 'wine', 'this', 
  10, 10, 'wine', 'this',
  0, 0, 'wine', 'that', 
  10, 10, 'wine', 'that',
)

ggplot(mydata, aes(x,y)) + facet_grid(data~more, scale='free') + theme_gray() + geom_point()

ggplot(mydata, aes(x,y)) + facet_grid(more~data, scale='free') + theme_gray() + geom_point()

我正在获取图形:

enter image description here

enter image description here

请注意,第一个图形更好地填充了面板中的空间。由于我的真实绘图使用了颜色编码,因此无需显示“ this”和“ that”,因此我想在第一个绘图中将其删除。但随后数据标签就变得很奇怪了。我希望他们像这样:

enter image description here

这与ggplot2: Using gtable to move strip labels to top of panel for facet_grid类似,但是其他链接对我来说不起作用,我认为情况有所不同。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

要使条带跨越列,您可能需要使用gtable函数(和几个grid函数)。

在解决方案中,将行添加到图表的gtable中,然后将这些条添加到新行中。条形图可以从头开始构建,但是绘制第二张图表时,条形图水平放置可能更容易,然后提取条形图。

(注意:这可能在下一个ggplot版本中轻易中断。)

library(ggplot2)
library(dplyr)


mydata = tribble(
  ~x, ~y, ~data, ~more,
  0, 50, 'iris', 'this', 
  10, 100, 'iris', 'this',
  0, 50, 'iris', 'that', 
  10, 100, 'iris', 'that',
  0, 0, 'wine', 'this', 
  10, 10, 'wine', 'this',
  0, 0, 'wine', 'that', 
  10, 10, 'wine', 'that',
)

### Construct two charts:
# 1. ToKeep - the data~more chart, but without the strip labels. 
# The strips across the tops of the two rows of panels will be added later.

(ToKeep <- ggplot(mydata, aes(x,y)) + 
           facet_grid(data ~ more, scale ='free') + 
           geom_point() +
           theme(strip.text.y = element_blank(),
                 strip.text.x= element_blank()) )

# 2. ToGetStrip - Get the strips from the more~data chart
ToGetStrip <- ggplot(mydata, aes(x,y)) + 
              facet_grid(more ~ data, scale = 'free') +
              geom_point()

# Get the ggplot grob
gt = ggplotGrob(ToGetStrip)

# Get the strips
library(gtable)
library(grid)
strip = gtable_filter(grid.force(gt), "strip-t")


# Make sure
grid.newpage()
grid.draw(strip$grobs[[1]])

grid.newpage()
grid.draw(strip$grobs[[2]])


## Add the strips to the ToKeep chart.

# Get ggplot grob
gt = ggplotGrob(ToKeep)

# Check heights and widths
gt$heights
gt$widths

# The 1null heights and widths are the panels' heights and widths.
# Add rows to the gtable immediately above the panel rows (that is, after row 9 then row 7).
# The height of the new rows is the height of the strip grobs.

gt <- gtable_add_rows(gt, height = strip$grobs[[1]]$height, pos = 9)
gt <- gtable_add_rows(gt, height = strip$grobs[[1]]$height, pos = 7)

# Add the strips to the new rows (  t = c(8, 11)  )
# and make sure they span the two columns of panels (  l = 5, r = 7   ) 
gt <- gtable_add_grob(gt, list(strip$grobs[[1]], strip$grobs[[2]]), t = c(8, 11), l = 5, r = 7)

# Draw it
grid.newpage()
grid.draw(gt)

enter image description here

以下是尝试根据面板位置选择行和列。但是,它没有经过2 X 2图表以外的测试。 (这对ggplot的更改可能更具弹性。)

# Construct the two charts
ToKeep <- ggplot(mydata, aes(x,y)) + 
           facet_grid(data ~ more, scale ='free') + 
           geom_point() +
           theme(strip.text.y = element_blank(),
                 strip.text.x= element_blank())


ToGetStrip <- ggplot(mydata, aes(x,y)) + 
              facet_grid(more ~ data, scale = 'free') +
              geom_point()

# Get the strips from the second chart
gt = ggplotGrob(ToGetStrip)

library(grid)
library(gtable)
strip = gtable_filter(grid.force(gt), "strip-t")


# Add rows to the ToKeep chart, and add the strips to the new rows
gt = ggplotGrob(ToKeep)
PanelPos = subset(gt$layout, grepl("panel", gt$layout$name), select = t:r)

PanelRows = rev(unique(PanelPos$t))
for(i in seq_along(PanelRows)) {
gt <- gtable_add_rows(gt, height = strip$grobs[[1]]$height, pos = PanelRows[i]-1)
}

PanelRows = unique(subset(gt$layout, grepl("panel", gt$layout$name), select = t, drop = TRUE))
gt <- gtable_add_grob(gt, strip$grobs, t = PanelRows - 1, l = min(PanelPos$l), r = max(PanelPos$r))

# Draw it
grid.newpage()
grid.draw(gt)

答案 1 :(得分:0)

我还没有看到这样一种方法来使条带标头跨多个列桥接,但是您可以通过隐藏x轴条形标头来实现类似的目的:

ggplot(mydata, aes(x,y)) + 
  geom_point() + 
  facet_grid(data~more, scale='free') + 
  theme_gray() + 
  theme(strip.background.x = element_blank(), 
        strip.text.x = element_blank()
)

enter image description here