如何从 R 绘图图中获取坐标

Oli*_*OUY 6 r shiny plotly shinyjs

我一直在努力像疯了一样要解决的显然是最基本的问题。想象一下,您有一个散点图,例如…… 10 个标记。我想这个图是在 Shiny 环境中使用 plotly 生成的。

使用event_data("plotly_click")代码可以轻松获得这些标记的坐标。

现在假设您不需要这些标记的坐标,而是通过鼠标点击生成的坐标,但恰好在不存在标记的地方(例如,因为您想在那里设置一个新标记,并且您想重新使用来自鼠标点击的信息)。

我无法使用onclick(),或其他方式获得这种行为。

任何的想法 ?

Max*_*ers 7

您可以将 D3 事件侦听器添加到您的绘图中

Plotly.d3.select('.plotly').on('click', function(d, i) {})
Run Code Online (Sandbox Code Playgroud)

进而

  • 根据点击位置(d3.event.layerXresp.)检索相对 x 和 y 值layerY
  • 调整相对图形位置(document.getElementsByClassName('bg')[0].attributes['x'] )
  • 最后根据轴范围计算新值 ( myPlot.layout.xaxis.range[0])

然后将新值xy值推送到现有图表

Plotly.extendTraces(myPlot, {
      x: [[x]],
      y: [[y]]
    }, [1]);
Run Code Online (Sandbox Code Playgroud)

完整的R代码

library("plotly")
library("htmlwidgets")

p <- plot_ly(x = c( -2, 0, 2 ),y = c( -2, 1, 2), type = 'scatter' ,mode = 'lines+markers') %>% 
  add_trace(x=c(-1,0.4,2),y=c(2, 0, -1),type='scatter',mode='lines+markers') %>% 
  layout(hovermode='closest')
javascript <- "
var myPlot = document.getElementsByClassName('plotly')[0];
Number.prototype.between = function (min, max) {
  return this >= min && this <= max;
};

Plotly.d3.select('.plotly').on('click', function(d, i) {
  var e = Plotly.d3.event;
  var bg = document.getElementsByClassName('bg')[0];
  var x = ((e.layerX - bg.attributes['x'].value + 4) / (bg.attributes['width'].value)) * (myPlot.layout.xaxis.range[1] - myPlot.layout.xaxis.range[0]) + myPlot.layout.xaxis.range[0];
    var y =((e.layerY - bg.attributes['y'].value + 4) / (bg.attributes['height'].value)) * (myPlot.layout.yaxis.range[0] - myPlot.layout.yaxis.range[1]) + myPlot.layout.yaxis.range[1]
  if (x.between(myPlot.layout.xaxis.range[0], myPlot.layout.xaxis.range[1]) && 
y.between(myPlot.layout.yaxis.range[0], myPlot.layout.yaxis.range[1])) {
    Plotly.extendTraces(myPlot, {
      x: [[x]],
      y: [[y]]
    }, [1]);
  }
});"
p <- htmlwidgets::prependContent(p, onStaticRenderComplete(javascript), data=list(''))
p
Run Code Online (Sandbox Code Playgroud)

交互式 JavaScript 示例

Plotly.d3.select('.plotly').on('click', function(d, i) {})
Run Code Online (Sandbox Code Playgroud)
Plotly.extendTraces(myPlot, {
      x: [[x]],
      y: [[y]]
    }, [1]);
Run Code Online (Sandbox Code Playgroud)


闪亮的例子

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

ui <- fluidPage(
  plotlyOutput("plot")
)

server <- function(input, output) {
   javascript <- "
function(el, x){
  Number.prototype.between = function (min, max) {
   return this >= min && this <= max;
  };

  Plotly.d3.select('.plotly').on('click', function(d, i) {
  var e = Plotly.d3.event;
  var bg = document.getElementsByClassName('bg')[0];
  var x = ((e.layerX - bg.attributes['x'].value + 4) / (bg.attributes['width'].value)) * (el.layout.xaxis.range[1] - el.layout.xaxis.range[0]) + el.layout.xaxis.range[0];
  var y =((e.layerY - bg.attributes['y'].value + 4) / (bg.attributes['height'].value)) * (el.layout.yaxis.range[0] - el.layout.yaxis.range[1]) + el.layout.yaxis.range[1]
  if (x.between(el.layout.xaxis.range[0], el.layout.xaxis.range[1]) && y.between(el.layout.yaxis.range[0], el.layout.yaxis.range[1])) {
    Plotly.extendTraces(el, {
     x: [[x]],
     y: [[y]]
    }, [1]);
  }
});
}"
  output$plot <- renderPlotly({
    plot_ly(x = c( -2, 0, 2 ),y = c( -2, 1, 2), type = 'scatter' ,mode = 'lines+markers') %>% 
    add_trace(x=c(-1,0.4,2),y=c(2, 0, -1),type='scatter',mode='lines+markers') %>% 
    layout(hovermode='closest') %>% onRender(javascript)
  })
}

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)