在 gtable 对象中设置宽度折叠图;这曾经有效,但现在不再有效。

Posted

技术标签:

【中文标题】在 gtable 对象中设置宽度折叠图;这曾经有效,但现在不再有效。【英文标题】:Setting width in gtable object collapses plot; this used to work but it doesn't anymore. 【发布时间】:2016-06-19 17:39:35 【问题描述】:

以下代码曾经可以工作,但现在不行了。有人知道发生了什么吗?一定是底层 gtable 代码发生了一些变化。

require(cowplot) # for plot_grid()
require(grid) # for unit_max()

# make two plots
plot.iris <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) + 
  geom_point() + facet_grid(. ~ Species) + stat_smooth(method = "lm") +
  background_grid(major = 'y', minor = "none") + 
  panel_border()
plot.mpg <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(cyl))) + 
  geom_point(size=2.5)

g.iris <- ggplotGrob(plot.iris) # convert to gtable
g.mpg <- ggplotGrob(plot.mpg) # convert to gtable

iris.widths <- g.iris$widths[1:3] # extract the first three widths, 
                                  # corresponding to left margin, y lab, and y axis
mpg.widths <- g.mpg$widths[1:3] # same for mpg plot
max.widths <- unit.pmax(iris.widths, mpg.widths) # calculate maximum widths
g.iris$widths[1:3] <- max.widths # assign max. widths to iris gtable
g.mpg$widths[1:3] <- max.widths # assign max widths to mpg gtable

plot_grid(g.iris, g.mpg, labels = "AUTO", ncol = 1)

结果图如下:

它应该是这样的(y 轴线完全垂直对齐):

错误似乎发生在这一行:

g.iris$widths[1:3] <- max.widths

任何见解将不胜感激。

请注意,类似的解决方案已经使用了很长时间,请参见例如here. 而cowplot 中的plot_grid() 函数也使用这样的代码来对齐绘图,它仍然有效。所以这让我完全迷惑了。

【问题讨论】:

【参考方案1】:

编辑 对于grid 3.3.0 版,这不再是问题。即下面包含grid:::unit.list()的代码行可以删除。

问题在于单位的设置方式。看g.iris$widths。您会注意到数字在那里,但单位已被删除。请参阅此question and answer 和this one。将图转成gtables后,需要:g.iris$widths = grid:::unit.list(g.iris$widths)

require(grid) # for unit_max()
require(cowplot)

# make two plots
plot.iris <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) + 
  geom_point() + facet_grid(. ~ Species) + stat_smooth(method = "lm") + 
  background_grid(major = 'y', minor = "none") + 
  panel_border()
plot.mpg <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(cyl))) + 
  geom_point(size=2.5) 

g.iris <- ggplotGrob(plot.iris) # convert to gtable   
g.mpg <- ggplotGrob(plot.mpg) # convert to gtable

g.iris$widths = grid:::unit.list(g.iris$widths)   
g.mpg$widths =  grid:::unit.list(g.mpg$widths)

iris.widths <- g.iris$widths[1:3] # extract the first three widths, 
                                  # corresponding to left margin, y lab, and y axis
mpg.widths <- g.mpg$widths[1:3] # same for mpg plot

max.widths <- unit.pmax(iris.widths, mpg.widths) # calculate maximum widths

g.iris$widths[1:3] <- max.widths # assign max. widths to iris gtable
g.mpg$widths[1:3] <- max.widths # assign max widths to mpg gtable

plot_grid(g.iris, g.mpg, labels = "AUTO", ncol = 1)

【讨论】:

确实,grid:::unit.list() 已经需要一段时间了;我忘记了我何时开始注意到 ggplot2 的损坏。这种未导出的网格函数几乎已成为进行这种绘图对齐的要求,这在包中可能会出现问题。 非常感谢!轴线问题是最新的 ggplot2 版本 2.1.0 中的一个错误。它已经在 github 中修复,提交给 CRAN 待定。 我删除了对轴线的引用。 要明确:轴线错误在ggplot2 2.1.0中。我已经修复了 cowplot 以解决该错误并将其提交给 CRAN。 @baptiste 使用最新的 R 开发版本,这个例子现在应该可以在没有 grid:::unit.list() 的情况下工作:stat.ethz.ch/pipermail/r-devel/2016-March/072434.html

以上是关于在 gtable 对象中设置宽度折叠图;这曾经有效,但现在不再有效。的主要内容,如果未能解决你的问题,请参考以下文章

如何在GWT DataGrid中设置标题单元格宽度

如何根据条件在可折叠面板中设置折叠值?-EXTJS

有没有办法在 Xamarin 中设置 MasterDetailPage.Master 的宽度?

在工具栏中设置灵活宽度的文本字段

在css中设置主要内容相对于响应侧边栏宽度的边距[重复]

在 Google Maps api v2 中设置自定义 InfoWindow 的宽度