【发布时间】:2010-06-30 16:13:45
【问题描述】:
如果我使用par(mfrow=...) 创建一个多图窗口,是否可以将数据发送到特定图(即“左下角的图”),或者绘图总是必须按顺序进行?是否有用于 R 的包做这样的事情?
对于那些感兴趣的人来说,这个问题的出现是因为 R 是一个单线程应用程序,并不适合实时可视化。我有多个从异步生成数据的外部源进入 R 的实时数据流(因此数据流并不总是以相同的顺序出现)。这导致 R 每次更新时都会翻转数据可视化图的顺序。
【问题讨论】:
如果我使用par(mfrow=...) 创建一个多图窗口,是否可以将数据发送到特定图(即“左下角的图”),或者绘图总是必须按顺序进行?是否有用于 R 的包做这样的事情?
对于那些感兴趣的人来说,这个问题的出现是因为 R 是一个单线程应用程序,并不适合实时可视化。我有多个从异步生成数据的外部源进入 R 的实时数据流(因此数据流并不总是以相同的顺序出现)。这导致 R 每次更新时都会翻转数据可视化图的顺序。
【问题讨论】:
你可以使用split.screen():
par(bg = "white") # erase.screen() will appear not to work
# if the background color is transparent
# (as it is by default on most devices).
split.screen(c(2,1)) # split display into two screens
split.screen(c(1,3), screen = 2) # now split the bottom half into 3
screen(1) # prepare screen 1 for output
plot(10:1)
screen(4) # prepare screen 4 for output
plot(10:1)
【讨论】:
看看help(layout)。这允许您指定内容、位置和大小。
一旦绘制,我认为您不会只是部分地重新绘制。但是您可以使用dev.set() 等在不同的“绘图设备”(即窗口)之间切换;见help(dev.list)。
【讨论】:
请注意,这里建议的答案是使用 split.screen()。它可能有效,但根据 split.screen 帮助文件:“使用这些功能的推荐方法是在另一个屏幕上选择和绘图之前,完全绘制一个绘图和所有添加(即点和线)到基础绘图. 与返回屏幕以添加到现有绘图相关的行为是不可预测的,并且可能导致不易看到的问题。”
在回答我的问题时,有一个更有用的解决方案,使用 par(mfg) 选项:
【讨论】:
另一种选择是实现一个小 GUI,例如RGtk2 或 RTclTk。
我通常对想要实时更改的图表执行此操作,效果很好。
例如,使用 RGtk2 和 cairoDevice 您可以执行类似的操作(我假设您有 Glade 界面)
# Helper function to get a widget from the Glade interface
getWidget <- function(name)
{
return (interface$getWidget(name))
}
interface <- gladeXMLNew("interface.glade", root="mainWindow")
# Our cairo devices (to draw graphics).
# plot1, plot2, and plot3 are GtkDrawingArea widgets
asCairoDevice(getWidget("plot1"))
# dev.cur() will give the device number of the last device we created
# You'll use this to switch device when you draw in different plots
# Storing the device number is important because you may have other
# devices open from other unrelated plots
# (so never assume they'll just start from 1 and be sequential!!!)
plot1.dev <- as.integer(dev.cur())
asCairoDevice(getWidget("plot2"))
plot2.dev <- as.integer(dev.cur())
asCairoDevice(getWidget("plot3"))
plot3.dev <- as.integer(dev.cur())
# To draw in a specific plot you just do
dev.set(plot2.dev)
plot(....)
这还有许多其他优点,例如能够轻松地将图形放置在您想要的位置(使用 Glade 界面设计器)以及可以通过特定按钮进行用户交互(例如,您可能有一个“暂停采集”按钮) .
【讨论】: