2017-11-18 123 views
1

我有一个应用程序,我试图改变点的大小或颜色或符号。 点是用户点击的对象。 点击一个点会在我的程序中创建一个弹出窗口,显示另一个数据集链接到属于被点击的点的rownumber列中的ID值。我在演示应用程序中包含了事件流(没有弹出窗口)用于点击事件。在R发光的情节中改变一个散点图中的单个点

我试图根据答案here更改点为一个情节2d散点图。但是,将代码应用于我的3D图似乎不起作用。

一点点额外的背景资料:我建立一个程序来分析3D分散的数据和我的应用程序包含了几个这样的3D绘图

有谁知道如何使这项工作?

下面的应用程序包含的代码,这两个二维(评论)和3D绘图对象,以显示工作和非工作情况,是@Maximilian彼得斯给予代码的直接修改

谢谢你的任何帮帮我!

奖金问题:假设我们可以把它的3dplot工作,我也想弄清楚如何根据存储在一个反应​​变量数更改JavaScript代码来改变一个点(即值$活动点),而不是点击事件,因为我将允许用户循环点和一个< - 和 - >按钮来更改点ID,我们正在从中检索附加信息。

library(shiny) 
library(plotly) 
library(htmlwidgets) 

ui <- fluidPage(
    plotlyOutput("plot"), 
    textOutput('messageNr') 
) 

javascript <- " 
function(el, x){ 
el.on('plotly_click', function(data) { 
colors = []; 
var base_color = document.getElementsByClassName('legendpoints')[data.points[0].curveNumber].getElementsByTagName('path')[0].style['stroke'] 
for (var i = 0; i < data.points[0].data.x.length; i += 1) { 
colors.push(base_color) 
}; 
colors[data.points[0].pointNumber] = '#000000'; 
Plotly.restyle(el, 
{'marker':{color: colors}}, 
[data.points[0].curveNumber] 
); 
//make sure all the other traces get back their original color 
for (i = 0; i < document.getElementsByClassName('plotly')[0].data.length; i += 1) { 
if (i != data.points[0].curveNumber) { 
colors = []; 
base_color = document.getElementsByClassName('legendpoints')[i].getElementsByTagName('path')[0].style['stroke']; 
for (var p = 0; p < document.getElementsByClassName('plotly')[0].data[i].x.length; p += 1) { 
colors.push(base_color); 
} 
Plotly.restyle(el, 
{'marker':{color: colors}}, 
[i]); 
} 
}; 
}); 
}" 


server <- function(input, output, session) { 
    row.names(mtcars) <- 1:nrow(mtcars) 
    colorscale <- c("blue", "red", "yellow") 

    values <- reactiveValues() 

    output$plot <- renderPlotly({ 
    values$point <- event_data("plotly_click", source = "select") 

    plot_ly(mtcars, 
      x = ~mpg, 
      y = ~cyl, 
      z = ~wt, 
      type = "scatter3d", 
      color = as.factor(mtcars$gear), 
      colors = colorscale, 
      mode = "markers", 
      source = "select", 
      showlegend = F)%>% 
    add_markers() %>% onRender(javascript) 
    }) 



observeEvent(values$point, { 
    values$row <- as.numeric(values$point$pointNumber) +1 
    values$ID <- rownames(mtcars)[values$row] 
    ### the values$ID is what I use to look up the corresponding dataset in other dataframes containing the detailed info of a datapoint in the 
    ### summary data set that is used to create the real scatter3d plots in which the user clicks. 
    output$messageNr <- renderText(values$ID) 
    }) 
} 

# server <- function(input, output, session) { 
# 
# nms <- row.names(mtcars) 
# 
# output$plot <- renderPlotly({ 
#  p <- ggplot(mtcars, aes(x = mpg, y = wt, col = as.factor(cyl))) + 
#  geom_point() 
#  ggplotly(p) %>% onRender(javascript) 
# 
# }) 
# } 

shinyApp(ui, server) 
+0

如果有人认为他可以帮助这个,也许我们可以在聊天聊天,所以我可以更好地解释我正在努力实现什么 – Mark

回答

2

你可以添加一个跟踪只是突出一点,在响应改变单点的位置,以一个Javascript eventListener

library(shiny) 
library(plotly) 
library(htmlwidgets) 

ui <- fluidPage(
    plotlyOutput("plot"), 
    textOutput('messageNr') 
) 

javascript <- " 
function(el, x) { 
    el.on('plotly_click', function(data) { 

    var highlight_trace = el.data.length - 1; 
    //the coordinates of the point which was clicked on 
    //is found in data 
    var newPoint = {x: data.points[0].x, 
        y: data.points[0].y, 
        z: data.points[0].z}; 

    //update the plot data and redraw it 
    if (el.data[highlight_trace].x[0] != newPoint.x || 
     el.data[highlight_trace].y[0] != newPoint.y || 
     el.data[highlight_trace].z[0] != newPoint.z) { 
     el.data[highlight_trace].x[0] = newPoint.x; 
     el.data[highlight_trace].y[0] = newPoint.y  
     el.data[highlight_trace].z[0] = newPoint.z 
     Plotly.redraw(el); 
     } 
    }) 
} 
" 


server <- function(input, output, session) { 

    output$plot <- renderPlotly(
    { 
     p <- plot_ly() 
     p <- add_trace(p, 
       data = mtcars, 
       x = ~mpg, 
       y = ~cyl, 
       z = ~wt, 
       color = as.factor(mtcars$gear), 
       type = 'scatter3d', 
       mode = "markers") 
     p <- add_trace(p, 
        x = c(20), 
        y = c(5), 
        z = c(4), 
        name = 'highlight', 
        type = 'scatter3d', 
        mode = 'markers', 
        marker = list(size = 15, 
            opacity = 0.5)) %>% onRender(javascript) 
     p 
    } 
) 
} 

shinyApp(ui, server) 
  • el是你的阴谋存储
  • “厄尔尼诺JavaScript的元素。数据”就是Plotly存储
  • if块可以确保如果点击
  • 一个新的点,如果是点击一个点的图形仅仅是重新绘制你的图中的数据,为彰显跟踪的数据被覆盖和剧情是redrawň

  • 请确保您使用的是最新版本的Plotly的,否则点击事件可能无法正常工作或者是越野车
  • 在你原来的代码跟踪绘制可能是因为add_markers()

互动JavaScript示例的多次(除去showlegend看到它),

Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/3d-scatter.csv', function(err, rows) { 
 
     function unpack(rows, key) { 
 
     return rows.map(function(row) { 
 
      return row[key]; 
 
     }); 
 
     } 
 
     var trace1 = { 
 
     x: unpack(rows, 'x1').slice(0, 30), 
 
     y: unpack(rows, 'y1').slice(0, 30), 
 
     z: unpack(rows, 'z1').slice(0, 30), 
 
     mode: 'markers', 
 
     marker: { 
 
      size: 12, 
 
      line: { 
 
      color: 'rgba(217, 217, 217, 0.14)', 
 
      width: 0.5 
 
      }, 
 
      opacity: 0.8 
 
     }, 
 
     type: 'scatter3d' 
 
     }; 
 

 
     var trace3 = { 
 
     x: [0], 
 
     y: [0], 
 
     z: [0], 
 
     name: 'highlight', 
 
     mode: 'markers', 
 
     type: 'scatter3d', 
 
     marker: { 
 
      size: 24, 
 
      opacity: 0.5 
 
     } 
 
     }; 
 
     var data = [trace1, trace3]; 
 
     var layout = { 
 
     margin: { 
 
      l: 0, 
 
      r: 0, 
 
      b: 0, 
 
      t: 0 
 
     } 
 
     }; 
 
     
 
     myDiv = document.getElementById('myDiv'); 
 
     Plotly.newPlot(myDiv, data); 
 

 
     myDiv.on('plotly_click', function(data) { 
 
     var highlight_trace = myDiv.data.length - 1; 
 
     //the coordinates of the point which was clicked on 
 
     //is found in data 
 
     var newPoint = { 
 
      x: data.points[0].x, 
 
      y: data.points[0].y, 
 
      z: data.points[0].z 
 
     }; 
 

 
     //update the plot data and redraw it 
 
     if (myDiv.data[highlight_trace].x[0] != newPoint.x || 
 
      myDiv.data[highlight_trace].y[0] != newPoint.y || 
 
      myDiv.data[highlight_trace].z[0] != newPoint.z) { 
 
      myDiv.data[highlight_trace].x[0] = newPoint.x; 
 
      myDiv.data[highlight_trace].y[0] = newPoint.y 
 
      myDiv.data[highlight_trace].z[0] = newPoint.z 
 
      Plotly.redraw(myDiv); 
 
     } 
 
     }); 
 

 

 
    })
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> 
 
<div id='myDiv'></div>

+0

马克西米利安,绝对惊人的,在几行代码! 我现在要在10k点的情节(我真实的数据集)上测试它。 一个小的跟进问题:在代码中,我看不到第一眼看什么决定了高亮度球体的大小,形状或颜色......但等等,现在我知道了,它全部设置在使用的add_trace中通过绘制点击点的副本来“模拟”高光效果。可爱!如果可以的话,会给+10这个 – Mark

+0

好的,增加的信息,我设法给add_trace点一个特定的颜色。我没有像在主轨迹中那样使用colors = c('..... colors here'),而是设法通过在标记= list(....)部分中添加“color ='black' add_trace – Mark