首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过htmlWidgets onRender()函数添加多行绘图

通过htmlWidgets onRender()函数添加多行绘图
EN

Stack Overflow用户
提问于 2017-10-08 23:26:34
回答 1查看 535关注 0票数 1

我试图获取一个空白的绘图,将其从htmlWidgets中输入到htmlWidgets()中,并在onRender()函数中添加许多行。在下面的代码中,我使用了一个有100行(100行)的数据集,当我运行应用程序时,这100行是在onRender()中在大约1秒内绘制的。但是,当我将数据集更改为有2000行时,需要10秒钟才能将它们全部绘制出来。

我正试图在50,000至100,000行的数据集上实现这一目标。这显然是问题的原因,因为缓慢的代码目前!

我目前实现该功能的方式是:

  1. 在R中创建一个名为pcpDat的数据帧。它有100行和6列数值数据。
  2. 在R中创建一个名为p的空白图
  3. 将数据帧pcpDat和p绘图到onRender()
  4. 在onRender()中:我有一个xArr对象,它只包含值0、1、2、3、4、5。对于数据帧的每一行,我将其6个值重构为一个名为yArr的数字向量。然后,对于数据的每一行,我创建一个,其中包含xArr和yArr,以便为6x和6y值绘制。然后,这个实际跟踪对象为原始数据帧的每一行创建一条橙色行。

把这么多行画成图,似乎很傻!我的推理是,我试图最终添加功能,这样用户就可以使用Plotly来选择地块上的一个区域,并且只查看截取该区域的行(其余的行将被删除)。这就是为什么我希望这些台词是“互动的”。

这一切让我思考了几个问题:

  1. 我不熟悉JavaScript (这是onRender()函数的关键)。我想知道是否有可能在5秒内快速绘制5万到10万条线?
  2. 如果(1)的答案是有可能的话,我正在征求关于如何“加快”下面的代码片段的建议。如果没有太多的JavaScript技能,我很难确定什么是花费最多的时间。我可能无法有效地重建这些数据。

我很想听听关于这个话题的任何建议或意见。谢谢!

代码语言:javascript
复制
library(plotly)
library(ggplot2)
library(shiny)
library(htmlwidgets)
library(utils)

ui <- basicPage(

  plotlyOutput("plot1")
)

server <- function(input, output) {

  set.seed(3)
  f = function(){1.3*rnorm(100)}
  pcpDat = data.frame(ID = paste0("ID", 1:100), A=f(), B=f(), C=f(), D=f(), E=f(), F=f())
  pcpDat$ID = as.character(pcpDat$ID)
  plotPCP(pcpDat = pcpDat)

  colNms <- colnames(pcpDat[, c(2:(ncol(pcpDat)))])
  nVar <- length(colNms)

  p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(alpha=0) + xlim(0,(nVar-1)) +ylim(min(pcpDat[,2:(nVar+1)]),max(pcpDat[,2:(nVar+1)])) + xlab("Sample") + ylab("Count")
  gp <- ggplotly(p)

  output$plot1 <- renderPlotly({
    gp %>% onRender("
      function(el, x, data) {

      var origPcpDat = data.pcpDat
      var pcpDat = data.pcpDat

      var Traces = [];
      var dLength = pcpDat.length
      var vLength = data.nVar
      var cNames = data.colNms

      xArr = [];
      for (b=0; b<vLength; b++){
      xArr.push(b)
      }

      for (a=0; a<dLength; a++){
      yArr = [];
      for (b=0; b<vLength; b++){
      yArr.push(pcpDat[a][cNames[b]]);
      }
      var pcpLine = {
      x: xArr,
      y: yArr,
      mode: 'lines',
      line: {
      color: 'orange',
      width: 1
      },
      opacity: 0.9,
      }
      Traces.push(pcpLine);
      }
      Plotly.addTraces(el.id, Traces);
}", data = list(pcpDat = pcpDat, nVar = nVar, colNms = colNms))})
}

shinyApp(ui, server)

编辑:为了演示我试图做什么,我包括3张图片。它们显示了数据中有10行(行)的示例。第一个图像是用户最初看到的(所有10行)。然后,用户可以使用“框选择”工具并创建一个矩形(灰色)。对于它包含的所有x值,保留在矩形内的任何行都保持不变。在本例的第二个图像中,仍保留5行。之后,用户可以创建另一个矩形(灰色)。同样,对于它包含的所有x值,保留在矩形内的任何行都保持不变。在这个例子的第三个图像中,现在只剩下一条行了。这3张截图来自我的功能代码。所以,我确实有一个原型工作。然而,当我添加数千行时,它太慢了。

EN

回答 1

Stack Overflow用户

发布于 2017-10-09 02:09:49

如果您将您的ggplot和巧妙的javascript转换为plotly包标准,那么您将删除当前的额外步骤和计算。下面是最低限度的示例解决方案:

代码语言:javascript
复制
output$plot1 <- renderPlotly({

  plot_ly(type = "scatter", mode = "markers") %>%
    add_trace(
      x = ~wt,
      y = ~mpg,
      data = mtcars
    ) %>%
    layout(
      xaxis = list(title = "Sample"),
      yaxis = list(title = "Count")
    )

})

要完成隐藏的跟踪,可以将visible = "legendonly"吸引器设置为跟踪,用户可以打开或关闭这些跟踪。有关更多细节,请参见这些答案,1 & 2

您还可以使用输入和响应来限制您发送到的数据量,而不是每次您想要生成的所有数据都提供给它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46637047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档