【问题标题】:Why does this R ggplot2 code bring up a blank display device?为什么此 R ggplot2 代码会显示空白显示设备?
【发布时间】:2013-06-05 10:30:50
【问题描述】:

虽然 SO 通常不用于帮助解决错误,但它显示了特别简单且特别烦人的行为。如果您是ggplot2 用户,您可以在 10 秒或更短的时间内重现它。

正如这个 GitHub 问题:ggplot_gtable creates blank display 所说,以下代码

library(ggplot2)
stat = qplot(Sepal.Length, Petal.Length, data = iris, color = Species)
ggplot_gtable(ggplot_build(stat))

将产生一个空白设备。请注意,由于ggplot2 是一个图形库,因此某些命令可以调出图形设备来显示相关的绘图。具体来说,只需运行ggplot_build(stat) 就会显示一个情节。但这并不能解释这种行为。

我不确定如何调试这个(打印语句似乎并不合适或有用),ggplot2 开发社区似乎正在休假或其他什么,所以如果有经验的R 用户可以提供关于如何有效调试的建议,我将不胜感激。这是一个微不足道但非常烦人的错误。每次我运行看起来像 sn-p 的代码时,它都会显示一个空白设备,显示器会将焦点切换到该设备上,因此我必须单击它才能继续。

我可能做错了什么,并且我是唯一可以重现此错误的人。出于某种我无法想象的原因,这也可能是正常行为。如果您认为其中任何一个是真的,请告诉我。

我在 Debian Squeeze 上使用 ggplot2 0.9.3.1(最新版本)。

【问题讨论】:

  • 你想用ggplot_gtable(ggplot_build())做什么? (顺便说一句,有ggplotGrob()。我的猜测是在gtable创建过程中,需要一个开放的设备来解析某些类型的网格单元。
  • 在 OSX:10.7.5 /R: 3.0.1/ggplot2_0.9.3.1 从 GUI 1.60 (6475) 调用时不会发生,但在 R 会话开始时调用时会发生在 Terminal.app 中
  • @baptiste:ggplotGrob 的定义是ggplot_gtable(ggplot_build())。我习惯于把手放在 grob 桌子上。
  • @DWin 谢谢。这是有用的信息。所以它是特定于操作系统的。
  • 在 5 分钟窗口中添加了信息。事实证明,特定于接口。

标签: r debugging graphics ggplot2


【解决方案1】:

一些网格 grobs 的单位只能在绘图时解析,也就是说,一旦设备窗口打开。例如,文本 grobs 就是这种情况,因为它们的大小可能取决于(在最一般的情况下)父视口的 cexfontsize 参数(可以嵌套等)

library(grid)
widthDetails(textGrob("hi"))

ggplot2 的当前版本似乎在代码中使用 widthDetails 来构建图例 grobs(guides_build 函数)。可以想象,这可以用grobWidth 代替,除非 grob 大小太复杂。

【讨论】:

  • 谢谢。 grobWidth 的优势是什么?
  • 显然它没有打开一个窗口。但老实说,我从来没有完全理解这两者之间的区别,可能只有 Paul Murrell 以外的几个人可以肯定地说出来。
  • grobWidth 可以很好地代替widthDetails,但ggplot_gtable 最终会调用height_cm --> grid::convertWidth --> grid::convertUnit,最后一个需要打开的设备.
【解决方案2】:

我想知道它是否与 3 年前 R-Help 上的这个线程有关,@G.Grothendieck 的这个解决方法(复制材料如下)

https://stat.ethz.ch/pipermail/r-help/2010-December/263754.html

library(lattice)
library(zoo)

df <- data.frame(y = matrix(rnorm(24), nrow = 6), x = 1:6)
xyplot(zoo(df[1:4], df$x), type = "p")

plot.object <- xyplot(zoo(df[1:4], df$x), type = "p") 
# problem: a Quartz device is opened (on Mac OS X 10.6)

格罗腾迪克在回复中写道:

这也会在 Windows 上打开一个窗口。它发生在晶格内 当 lattice 发出 trellis.par.get 时。一种解决方法是打开 指向 null 的设备。在 Windows 上,这会起作用。我假设如果 你使用“/dev/null”它会在你的机器上工作。

png("NUL")
plot.object <- ...
dev.off()

【讨论】:

  • 这很有趣。我想知道这样的事情是否可以在这里选择。 @巴蒂斯特?也许添加到 r-help 线程的链接? Gmane 是我通常链接到的。我重新格式化了你的答案 - 你能同意吗?谢谢。
  • 感觉不是很优雅,但我想在某些情况下这是解决网格特性的唯一方法。我相信首选的空设备是pdf(file = NULL)
  • 将原始文本替换为stat.ethz.ch 的(真实)R-help 存档链接。我使用 MarkMail 进行搜索。
【解决方案3】:

我在 2019 年仍然遇到 R 3.6.1 这个问题。

我缺乏声誉,不允许我发表评论。所以我正在写另一个答案:

如果你的情节使用非标准字体,事情会变得有点棘手,比如说

library (ggplot2)
stat = qplot(Sepal.Length, Petal.Length, data = iris, color = Species) + 
  theme(text = element_text (family="DejaVu Sans"))

正如 baptiste 在回答中所解释的,需要输出设备来确定某些文本尺寸。但是,对于非标准字体,您需要适当的输出设备。如果你只是使用pdf(file=NULL) 就像 baptiste 所说的那样,你会得到错误的尺寸(并且警告说 'DejaVu Sans' 被另一种导致错误尺寸的字体取代)。为了解决这个问题,我必须打开一个能够呈现非标准字体的输出设备(比如一个临时文件):

cairo_pdf (tempfile (fileext=".pdf"))
grob = ggplot_gtable (ggplot_build (stat))
dummy = dev.off ()

希望这些信息有用。

【讨论】:

    【解决方案4】:

    问题似乎是由“颜色 = 物种”引起的。 如果替换为“group = Species”,则不再有空白显示设备。

    【讨论】:

    • 欢迎。这不是一个真正的答案——它是一个评论。如果您阅读了其他(完整)答案,您就会明白为什么group = Species 不会导致问题,而colour = Species 会导致问题。
    • @mnel 同意。 user2640757,请将此更改为评论。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    相关资源
    最近更新 更多