交互式地将点添加到plotly R而不重绘背景图

时间:2017-02-22 04:51:37

标签: javascript r plotly htmlwidgets

下面的MWE过分简化了我的真正目标。但是,我有一个需要很长时间才能绘制的背景图像(在下面的示例中,它只是一个32 mtcars数据集值的散点图)。用户可以从我的背景图像中单击某些点,这将导致绘制新点。我的目标是在顶层重新绘制这些新点,而不需要重新绘制背景图像散点图以节省时间和计算。

我的MWE如下:

library(plotly)
library(htmlwidgets)

g <- ggplot(mtcars, aes(x=mpg, y=cyl)) + geom_point()
gP <- ggplotly(g)

gP %>% onRender("
          function(el, x) {
            myGraph = document.getElementById(el.id);

            el.on('plotly_click', function(e) {

              console.log(e)
              console.log(e.points[0].x)

              var trace1 = {
                x: [e.points[0].x-.3, e.points[0].x-.3, e.points[0].x+.3, e.points[0].x+.3],
                y: [e.points[0].y-.3, e.points[0].y+.3, e.points[0].y-.3, e.points[0].y+.3],
                type: 'scatter',
                fillColor : 'red', 
                size: 20
              };

              Plotly.addTraces(el.id, trace1);
           })}
           ")

当用户点击32个黑点中的任何一个时,在点击的黑点周围绘制四个彩色红点。这主要是有效的,如果你点击32个黑色数据点中的任何一个,你应该会看到围绕它绘制的四个彩色点。但是,我仍然在努力解决几个问题:

1)如何改善这一点,使四个彩色点不通过线连接?

2)如何使尺寸和fillColor实际工作?当我改变他们的价值观时,我认为它们没有效果。

3)这是一种合理的语法,使交互性和绘图尽可能快吗?我很确定背景图像没有以有效的方式重新绘制,但我很乐意听到有关它的确认,因为我是这个语法的新手。如果我要在顶层添加100个新点,这仍然有效吗?如果没有,我将很高兴听到有关改进语法的建议的建议。

谢谢。

1 个答案:

答案 0 :(得分:0)

  

1)我如何改进这一点,使四个彩色点不是   用线连接?

mode: 'markers'添加到您的trace对象

  

2)如何使尺寸和fillColor实际工作?当我改变   他们的价值观,我认为他们没有效果。

值必须位于marker对象内,fillColor必须为color

marker: 
{
    color: 'red',   
    size: 20        
}
  

3)这是一种合理的语法,使交互性和绘图尽可能快吗?我很确定背景图片是   不是以有效的方式重新绘制,而是希望听到   关于它的确认,因为我是这个语法的新手。如果我要加   顶层有100个新点,这仍然有效吗?如果   不,我将很高兴听到有关建议的建议   改进了语法。

这有点基于意见。问题是你使用ggplot来创建模板,这会创建一个非常复杂的情节。 100点后,每次点击后都会有一些延迟。

修正x / y轴范围会稍微改善绘图,因为如果新值超出旧值范围,图表需要调整大小。

gP %>% 
  layout(
    xaxis = list(range = c(8, 35)),
    yaxis = list(range = c(3, 9))
  )

如果您可以在不使用ggplotly的情况下绘制绘图,则只能创建一次跟踪,然后通过extendTraces附加值。

但我认为它是最好的,最后它是一个基于浏览器的库,而不是一个独立的程序。

library(plotly)
library(htmlwidgets)

g <- ggplot(mtcars, aes(x=mpg, y=cyl)) + geom_point()
gP <- ggplotly(g)
gP %>% 
 layout(
    xaxis = list(range = c(8, 35)),
    yaxis = list(range = c(3, 9))
  )

gP %>% onRender("
function(el, x) {
  myGraph = document.getElementById(el.id);
  el.on('plotly_click', function(e) 
    {

      var trace1 = {
        x: [],
        y: [],
        mode: 'markers',
        marker: {
          color: 'red',   
          size: 20
        }
      };
      for (var i = 0; i < 100; i+= 1){
        trace1.x.push(e.points[0].x + Math.random() - 0.5)
        trace1.y.push(e.points[0].y + Math.random() - 0.5)
      }
    Plotly.addTraces(el.id, trace1);
  }
)}
")