使用无头显示器与rgl进行操作

9

我安装了 Xfvb 并创建了一个显示实例:

$ Xvfb :2 -screen 0 1280x960x24 &

我随后从源代码中分别安装了R 3.2.5和rgl 0.95.1441,并使用端口2上的DISPLAY连接打开了R。然后我尝试使用一些基本的rgl例程来运行测试rgl会话:

$ DISPLAY=:2 /usr/local/bin/R
R version 3.2.5 (2016-04-14) -- "Very, Very Secure Dishes"
...
> library(rgl)
> open3d()
> x <- sort(rnorm(1000))
> y <- rnorm(1000)
> z <- rnorm(1000) + atan2(x,y)
glX
 1
> plot3d(x, y, z, col=rainbow(1000))
> rgl.postscript("foo.pdf", fmt="pdf")
> sessionInfo()

这里的rgl.postscript()命令应该打印出一个包含传递给plot3d()的数据点渲染的PDF文件。然而,生成的PDF文件是空白的。
是否存在我安装或实例化Xvfb和/或R时的配置问题,导致显示问题?
以下是典型运行会话的日志:
R version 3.2.5 (2016-04-14)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Fedora release 14 (Laughlin)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  base

other attached packages:
[1] rgl_0.95.1441  optparse_1.3.2

loaded via a namespace (and not attached):
[1] getopt_1.20.0 methods_3.2.5

5 XSELINUXs still allocated at reset
SCREEN: 0 objects of 136 bytes = 0 total bytes 0 private allocs
DEVICE: 4 objects of 32 bytes = 128 total bytes 0 private allocs
CLIENT: 0 objects of 160 bytes = 0 total bytes 0 private allocs
WINDOW: 0 objects of 48 bytes = 0 total bytes 0 private allocs
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 56 bytes = 0 total bytes 0 private allocs
CURSOR: 0 objects of 8 bytes = 0 total bytes 0 private allocs
CURSOR_BITS: 0 objects of 8 bytes = 0 total bytes 0 private allocs
DBE_WINDOW: 0 objects of 24 bytes = 0 total bytes 0 private allocs
TOTAL: 5 objects, 144 bytes, 0 allocs
4 DEVICEs still allocated at reset
DEVICE: 4 objects of 32 bytes = 128 total bytes 0 private allocs
CLIENT: 0 objects of 160 bytes = 0 total bytes 0 private allocs
WINDOW: 0 objects of 48 bytes = 0 total bytes 0 private allocs
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 56 bytes = 0 total bytes 0 private allocs
CURSOR: 0 objects of 8 bytes = 0 total bytes 0 private allocs
CURSOR_BITS: 0 objects of 8 bytes = 0 total bytes 0 private allocs
DBE_WINDOW: 0 objects of 24 bytes = 0 total bytes 0 private allocs
TOTAL: 5 objects, 144 bytes, 0 allocs
1 PIXMAPs still allocated at reset
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 56 bytes = 0 total bytes 0 private allocs
CURSOR: 0 objects of 8 bytes = 0 total bytes 0 private allocs
CURSOR_BITS: 0 objects of 8 bytes = 0 total bytes 0 private allocs
DBE_WINDOW: 0 objects of 24 bytes = 0 total bytes 0 private allocs
TOTAL: 1 objects, 16 bytes, 0 allocs

除了 Fedora 14,我还测试了 CentOS Linux release 7.2.1511 下相同版本的 R 和 rgl。

在 Fedora 14 上,我运行的是:

xorg-x11-server-Xvfb.x86_64   v1.9.5-2.fc14

在CentOS 7系统上,我正在运行:

xorg-x11-server-Xvfb.x86_64   v1.17.2-10.el7

在两个测试服务器上,当我运行我的测试R脚本时,rgl.postscript()生成一个空白的白色PDF文件,rgl.snapshot()生成一个空白的黑色PNG文件(同时输出相同的Xvfb日志)。需要强调的是,我要创建的是包含渲染场景的矢量格式PDF文件。虽然rgl.snapshot()可以帮助排除问题的原因,但该调用返回的是PNG位图,而不是矢量格式的PDF。对于我的目的,位图不是最终产品有用的。
除了使用传递给它的DISPLAY变量设置运行R之外,我还使用了export
$ DISPLAY=:2 /usr/local/bin/R

或者:

$ export DISPLAY=":2" 
$ /usr/local/bin/R
...

任何一种方法都会得到相同的结果。
如果有其他细节有用,请随时留下评论,我会尽力跟进。
无论 Fedora 14 还是 CentOS 7 盒子都不应该有专有的 libgl 驱动程序。据我所知,这些都是独立的无头服务器。Fedora 14 的盒子实际上是一个虚拟机。如果有特定的确认方式,请告诉我。
在 Fedora 14 无头服务器下安装了以下的 Xdummy 包:
xorg-x11-drv-dummy.x86_64   v0.3.4-1.fc14

在 CentOS 7 机器上:
xorg-x11-drv-dummy.x86_64   v0.3.6-21.el7

在CentOS 7服务器上,我运行Xdummy脚本来在:10上创建一个显示器。
$ sudo ./Xdummy -debug :10 -depth 16 -geom 1024x768

在另一个终端中,我运行R并测试rgl程序:
$ DISPLAY=":10" /usr/local/bin/R
...
> library(rgl)
> open3d()
> x <- sort(rnorm(1000))
> y <- rnorm(1000)
> z <- rnorm(1000) + atan2(x,y)
> plot3d(x, y, z, col=rainbow(1000))
> rgl.postscript("foo.pdf", fmt="pdf")

Xvfb 相似,生成的 PDF 文件是一个空白文档,不包含任何数据点。


我并不常使用Xvfb,但我认为它通常不会保留完整的显示缓冲区。这可能是可配置的;希望有人可以帮助解决。无头显示的备选方案是选择null设备,并使用rglwidget输出WebGL,然后在浏览器中查看(或打印)结果,或者可能使用新的writeASY函数编写Asymptote源代码,并使用它来产生Postscript。 - user2554330
感谢您的建议。为了澄清,我想自动化生成PDF输出,因此通过Web浏览器的交互式解决方案可能不适用于此处。 - Alex Reynolds
尝试使用rgl.snapshot创建一个PNG文件,这样可以行吗?另外,请发布您的sessionInfo - 这可能是相关的。 - Mike Wise
rgl.snapshot 调用返回指定尺寸的黑色空白 PNG 文件。我已经在我的问题中添加了 sessionInfo 记录。感谢您可能认为有用的任何反馈。 - Alex Reynolds
1
rgl.useNULL(TRUE) 可以用于 writeASY()(用于编写 Asymptote 代码)或 rglwidget()(用于编写 Javascript),但不能与 rgl.postscript 或 rgl.snapshot 一起使用。 - user2554330
显示剩余10条评论
1个回答

3
这似乎与rgl包密切相关。假设我们放弃Xvfb及其相关内容,转而使用Cairo,并将rgl替换为plot3D:
library(Cairo)
library(plot3D)
CairoPDF()
x <- sort(rnorm(1000))
y <- rnorm(1000)
z <- rnorm(1000) + atan2(x, y)
scatter3D(x, y, z)
dev.off()

这仍需要在X11下运行(即xterm),但避免弹出X11窗口,并在 Rplots.pdf 中留下一个PDF图形(当然,您可以控制文件名以及绘图的许多其他细节)。

enter image description here

(转换为JPEG格式以便在此处插入,但它实际上是PDF格式。)

我不是给你点踩的人,所以我加了一票。这看起来很有趣,但我需要时间来调查它是否可以在没有X11帧缓冲的情况下工作,并且看看我是否能够重现现有的R/rgl脚本。感谢提供一个看起来像是rgl潜在替代品的东西。 - Alex Reynolds
@AlexReynolds,两年过去了,三个赞也有了,我回答这个问题时它的悬赏是500分,但我还是没能获得它? - cdlane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接