简体   繁体   English

使用strip.y作为strip.x而不翻转facet_grid轴

[英]Use strip.y as strip.x without flipping the facet_grid axis

With the code 随着代码

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

I am getting the graphics: 我正在获取图形:

在此输入图像描述

在此输入图像描述

Please note, how much better the first graph fills out the space in the panels. 请注意,第一张图填充面板中的空间要好多少。 Because of the color coding my real plot, I do not need to show "this" and "that", so I would like to get rid of it in the first plot. 由于我的真实情节的颜色编码,我不需要显示“this”和“that”,所以我想在第一个情节中摆脱它。 But then the data labels are weird to the side. 但随后数据标签很奇怪。 I would prefer if they were like this: 我希望他们是这样的:

在此输入图像描述

This is similar to ggplot2: Using gtable to move strip labels to top of panel for facet_grid , but that other link did not work for me and the situation is a little different, I think. 这类似于ggplot2:使用gtable将条带标签移动facet_grid的面板顶部 ,但是其他链接对我来说不起作用,我认为情况有点不同。

How can I do this? 我怎样才能做到这一点?

To get the strips to span the columns, you will probably need to use gtable functions (and a couple of grid functions). 要使条带跨越列,您可能需要使用gtable函数(以及几个grid函数)。

In the solution, rows are added to the chart's gtable, then the strips are added to the new rows. 在解决方案中,将行添加到图表的gtable中,然后将条带添加到新行中。 The strips could be constructed from scratch, but it's probably easier to draw a second chart with the strip oriented horizontally, then extract the strips. 条带可以从头开始构造,但是可能更容易绘制第二个图表,条带水平定向,然后提取条带。

(Note: This could easily break with the next ggplot version.) (注意:这可能很容易打破下一个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)

在此输入图像描述

Following is an attempt to select rows and columns in terms of panel positions. 以下是尝试根据面板位置选择行和列。 However, it has not been tested beyond your 2 X 2 chart. 但是,它尚未在2 X 2图表之外进行测试。 (This could be a little more resilient to changes to ggplot.) (对于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)

I haven't seen a way to get the strip headers to bridge multiple columns like that, but you could achieve something similar by just hiding the x axis strip headers: 我还没有看到一种方法来让strip头像这样连接多个列,但你可以通过隐藏x轴strip头来实现类似的东西:

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

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM