【问题标题】:How to transform a grob object to a ggplot object? (for drawing outside axes)如何将 grob 对象转换为 ggplot 对象? (用于绘制外轴)
【发布时间】:2019-12-05 08:12:03
【问题描述】:

我会很快告诉你这个问题是如何产生的。

我想在 ggplot 的轴之外绘制一些东西。即,围绕 x 轴刻度线标签的多边形。我找到了一种方法,方法是使用 annotation_custom()grid::polygonGrob() 函数并关闭剪辑。我想我的问题是我对这些对象还不太熟悉。我所知道的是,在我的操作之后,我得到了一个 grob 对象。这样就可以了,但我想使用cowplot 将其包含在绘图网格中。

这是我的代码:

# Required packages
library(ggplot2)
library(grid)
require(cowplot)

# dput(data_B)

data_B <- structure(list(n = c(3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 3L, 4L, 
5L, 6L, 7L, 8L, 9L, 10L), sample = structure(c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("sample_1", 
"sample_2"), class = "factor"), fraction = c(0.01, 0.05, 0.24, 
0.45, 0.19, 0.045, 0.01, 0.005, 0.005, 0.04, 0.225, 0.53, 0.14, 
0.04, 0.02, 0), err = c(0.002, 0.01, 0.04, 0.06, 0.034, 0.009, 
0.002, 0.001, 0.001, 0.008, 0.04, 0.05, 0.03, 0.008, 0.004, 0
)), class = "data.frame", row.names = c(NA, -16L))

# The plot
panel_B <- ggplot(data=data_B,(aes(x=n,y=fraction,fill=sample)))+
  geom_bar(stat = "identity",position=position_dodge()) +
  geom_errorbar(aes(ymin=fraction-err, ymax=fraction+err), 
                width=.2, position=position_dodge(.9)) +
  scale_fill_manual(values=c('#f2a340','#998fc2'))+
  scale_x_continuous(expand = c(0, 0),
                     breaks=c(seq(min(data_B$n),max(data_B$n),by = 1)),
                     limits = c(min(data_B$n),max(data_B$n))) +
  scale_y_continuous(expand = c(0, 0),
                     breaks=c(seq(0,0.6,by=0.1)),
                     limits = c(0,0.6)
  )

# Add polygons around tick mark labels (unfinished work)
panel_B <- panel_B + 
  annotation_custom(polygonGrob(x = c(-0.03,0.03,0),y = c(-0.09,-0.09,-0.02),
                                gp=gpar(col="black",fill=NA, lwd=3))
  ) +
  annotation_custom(polygonGrob(x = c(0.12,0.17,0.17,0.12),y = c(-0.09,-0.09,-0.03,-0.03),
                                gp=gpar(col="black",fill=NA, lwd=2))) 


# Turn off panel clipping
gt <- ggplot_gtable(ggplot_build(panel_B))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
panel_B <- grid.draw(gt)

# And a dummy version of a cowplot grid
plot_grid(c(),panel_B,nrow=2)

另外,我的问题是绘制的多边形不是固定的,但是当情节比例改变时往往会错位。也许有一个完全不同的方法。为任何 cmets 感到高兴。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    似乎有两个问题; (1) 您不能使用网格对象作为cowplot 操作的绘图安排的输入;(2) 您的polygonGrobs 的比例会随着您的设备窗口大小而改变。

    要解决第一个问题,您可以在代码中# Turn off panel clipping 之前的位置添加以下行,这也将关闭剪切,但仍允许您将绘图对象与cowplot 一起使用:

    panel_B <- panel_B + coord_cartesian(clip = "off") 
    

    第二个问题可能是定义多边形的单位问题。由于 x 轴本身有一个奇怪的高度,通常定义为sum(2.75pt, 1grobheight),因此在所有调整大小下会发生什么是完全不可预测的。但是,我发现如果您以“native”单位而不是“npc”来定义多边形,结果似乎更容易预测。

    # Add polygons around tick mark labels (unfinished work)
    panel_B <- panel_B + 
      annotation_custom(polygonGrob(x = c(-0.03,0.03,0),y = c(-0.09,-0.09,-0.02),
                                    gp=gpar(col="black",fill=NA, lwd=3), default.units = "native")
      ) +
      annotation_custom(polygonGrob(x = c(0.12,0.17,0.17,0.12),y = c(-0.09,-0.09,-0.03,-0.03),
                                    gp=gpar(col="black",fill=NA, lwd=2), default.units = "native"))
    

    【讨论】:

    • 感谢您的见解。我还找到了一种将 grob 转换回 ggplot 的方法:panel_B &lt;- ggpubr::as_ggplot(gt)
    • 你从哪里得到这个关于 x 轴高度的信息,sum(2.75pt, 1grobheight)? ty
    • 如果你使用ggplotGrob(panel_B)$height,你可以看到gtable中所有元素的高度。轴是第 8 个元素,从布局中 axis-b 条目的 t(op)/b(ottom) 值可以看出:ggplotGrob(panel_B)$layout
    • 你能看看我的问题吗:stackoverflow.com/questions/65429978/…谢谢
    • 恐怕我对情节一无所知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多