(关闭)R应用程序中的覆盖窗口小部件
tl;dr我想在(关闭)R应用程序中的覆盖窗口小部件,r,ggplot2,shiny,R,Ggplot2,Shiny,tl;dr我想在图像输出上叠加一个绘图输出。我没有CSS/HTML知识 我面临的全部问题: 另一个tl;dr我想在shiny中复制,而且必须快速 想象一个小的3x4x53D阵列,由单位正方形组成(总共60个正方形)。我希望用户分别可视化这三个平面。对于XY、YZ和XZ平面,我有三个imageOutput(或plotOutput)。在此,我将这些称为平面。比如(我只是在谷歌上搜索了这个,不是我的图片)。加载应用程序时,我渲染每个平面的中心,十字线指向(交叉?)平面的中心。现在,当用户单击任何平面,
图像输出
上叠加一个绘图输出
。我没有CSS/HTML知识
我面临的全部问题:另一个tl;dr我想在shiny中复制,而且必须快速 想象一个小的
3x4x5
3D阵列,由单位正方形组成(总共60个正方形)。我希望用户分别可视化这三个平面。对于XY、YZ和XZ平面,我有三个imageOutput
(或plotOutput
)。在此,我将这些称为平面
。比如(我只是在谷歌上搜索了这个,不是我的图片)。加载应用程序时,我渲染每个平面的中心,十字线指向(交叉?)平面的中心。现在,当用户单击任何平面
,比如XY时,我会得到单击的坐标,并用新的图像更新另一个平面
,在本例中是YZ和XZ,新的x
和y
坐标。同时更新所有三个的十字线。最终的结果就是这张图片。除此之外,所有三个都在不同的视图中
所以我已经有了这样做的代码,但是加载时间很痛苦。因为实际输入的尺寸~250 x 250 x 100
。三架飞机装载大约需要2-3秒。该应用程序应该提供一个界面,以便以最少的延迟快速、轻松地查看飞机。所以基本上,我要加快速度
关于使用的变量:
x()
是输入的反应式李>
meta()
是一种反应式,它存储x()
的维度李>
values$xyz
是长度为3的数组,用于十字线的x、y和z
我试图在这篇文章中获得尽可能多的细节,因为这是一个复杂的问题。请原谅邮件的长度
到目前为止,我已经尝试了一些方法:
第一个想法是在飞行中渲染飞机。我有ui
的plotOutput
,下面的代码是服务器的
output$plotXY <- renderPlot({
req(x())
par(oma = rep(0, 4), mar = rep(0, 4), bg = "black")
graphics::image(1:meta()$X, 1:meta()$Y,
x()[, , values$xyz[3]],
col = gray(0:64/64),
xlab = "", ylab = "",
axes = FALSE,
useRaster = T)
abline(h = values$xyz[2], v = values$xyz[1], col = "red")
})
这确实在一定程度上加快了这一进程,但却微不足道。我使用了microbenchmark
。也试过了,但还是没什么希望
决定首先将所有平面(所有XY、YZ和XZ)保存为临时文件中的png,并在需要时加载。现在在ui
中使用imageOutput
# preprocessing:
makePNG <- function(slice) {
outfile = tempfile(fileext = ".png")
dims = dim(slice)
png(outfile, width = dims[1], height = dims[2])
par(mar = c(0,0,0,0))
image(slice, useRaster=T, axes=F, col = gray(0:64/64))
dev.off()
return(outfile)
}
...
file_paths_XY <- apply(x(), 3, makePNG) # also in meta()
...
# loading images:
output$plotXY <- renderImage({
req(x())
pos = values$xyz[3]
file_path = meta()$file_paths_XY[pos]
list(
src = file_path
)
}, deleteFile = F)
最后一个更新:所以我们使用的服务器通常都在进行大量的模拟和其他工作,从而大大降低了代码的速度。虽然这个问题还没有解决,但我想我们看错了问题。不管怎样,我要把赏金颁给西蒙。谢谢你的回答。这种方法使用3D阵列,每个平面都是灰度图像。通过分别跟踪每种颜色,可以将其推广到rgb。灵感来自于在Matlab中处理矩阵
首先设置一些虚拟数据:
# GREY
G = runif(250*250*100)
G = array(G, c(250,250,100))
其中G是图像的灰度分量
假设选择了坐标X=40
。然后我们提取YZ平面
:
ptm = proc.time()
X = 40
YZ_panel = G[40,,]
这可以在ggplot中显示为图像:
g <- rasterGrob(YZ_panel, interpolate=TRUE)
qplot(c(1,10,10,1,1),c(1,1,25,25,1),geom="blank") +
annotation_custom(g, xmin=0, xmax=10, ymin=0, ymax=25) +
geom_line(aes(x=c(5,5), y=c(0,25)), color="red") +
geom_line(aes(x=c(0,10), y=c(10,10)), color="red") +
coord_fixed()
当然,您必须对每个平面重复此过程
您是否计划使其可复制?:')我不知道有什么好办法。有什么建议吗?将使用DetailsHanks更新线程以获取答案。我已经尝试过保存并加载为png(选项2)。虽然我没有尝试过qplot
。将尝试更新。此外,图像是灰度的。只有一个3D数组作为输入。更新:我试过了,但速度没有提高。每次检测到点击时保存和加载png可能太重了。我尝试使用imageOutput
并将文件路径作为src
传递,但同样不快。另外,您能否提到您在哪里分配了ptm
,以便我能够更好地了解代码的哪一部分花费了不到一秒钟的时间?谢谢答案更新为灰度,定义ptm
并删除保存png(因为这是不必要的)。速度只会提高。您是否检查了click observer的速度/性能?
ptm = proc.time()
X = 40
YZ_panel = G[40,,]
g <- rasterGrob(YZ_panel, interpolate=TRUE)
qplot(c(1,10,10,1,1),c(1,1,25,25,1),geom="blank") +
annotation_custom(g, xmin=0, xmax=10, ymin=0, ymax=25) +
geom_line(aes(x=c(5,5), y=c(0,25)), color="red") +
geom_line(aes(x=c(0,10), y=c(10,10)), color="red") +
coord_fixed()
proc.time() - ptm
user system elapsed
0.18 0.03 0.21