在交互式绘图中提取鼠标单击的精确坐标

Kas*_*sen 7 interactive r ggplot2 shiny plotly

简而言之:我正在寻找一种方法来获取由ggplot2和呈现的交互式x/y散点图中一系列鼠标位置(点击次数)的精确坐标ggplotly.

我知道plotly(和R的其他几个交互式绘图包)可以结合使用Shiny,其中box或lazzo select可以返回所选子空间内所有数据点的列表.这份名单将是巨大的大多数但是我分析,数据集的,我需要能够在R降价格式重复地做了分析(写几个,大多不到5-6,点坐标得多可读的).此外,我必须知道点击的确切位置,以便能够在不同数据集中的相同多边形点内提取点,因此一个数据集中选择内的点列表无用.

grid.locator()从格包功能做几乎就是我正在寻找(的一个包裹在FX gglocator),但我希望有一种方法可以做到通过渲染的互动情节中的相同plotly(或者别的我就不说了因为数据集通常是巨大的(参见下图),因此能够在几次迭代分析中非常感激能够以交互方式放大和缩小数据集.

在此输入图像描述

通常情况下,我必须多次重新调整轴的大小以模拟放大和缩小,这样做很多次都会耗费精力.正如你在上面的图中所看到的,图中有很多信息需要探索(图中的内存大约为300MB).

以下是reprex我目前在grid.locator静态情节中使用的一小部分:

library(ggplot2)
library(grid)

p <- ggplot(mtcars, aes(wt, mpg)) +
  geom_point()

locator <- function(p) {
  # Build ggplot object
  ggobj <- ggplot_build(p)

  # Extract coordinates
  xr <- ggobj$layout$panel_ranges[[1]]$x.range
  yr <- ggobj$layout$panel_ranges[[1]]$y.range

  # Variable for selected points
  selection <- data.frame(x = as.numeric(), y = as.numeric())
  colnames(selection) <- c(ggobj$plot$mapping$x, ggobj$plot$mapping$y)

  # Detect and move to plot area viewport
  suppressWarnings(print(ggobj$plot))
  panels <- unlist(current.vpTree()) %>%
    grep("panel", ., fixed = TRUE, value = TRUE)
  p_n <- length(panels)
  seekViewport(panels, recording=TRUE)
  pushViewport(viewport(width=1, height=1))

  # Select point, plot, store and repeat
  for (i in 1:10){
    tmp <- grid.locator('native')
    if (is.null(tmp)) break
    grid.points(tmp$x,tmp$y, pch = 16, gp=gpar(cex=0.5, col="darkred"))
    selection[i, ] <- as.numeric(tmp)
  }
  grid.polygon(x= unit(selection[,1], "native"), y= unit(selection[,2], "native"), gp=gpar(fill=NA))
  #return a data frame with the coordinates of the selection
  return(selection)
}

locator(p)
Run Code Online (Sandbox Code Playgroud)

从这里使用point.in.polygon函数根据选择对数据进行子集化.

一个可能的解决方案是将100x100的不可见点添加到绘图中,然后使用Shiny应用程序中的plotly_click功能event_data(),但这根本不是理想的.

在此先感谢您的想法或解决方案,我希望我的问题足够明确.

- 卡斯帕

小智 0

我用的是ggplot2。除了https://shiny.rstudio.com/articles/plot-interaction.html上的材料之外,我还想提一下以下内容:

首先,创建绘图时,不要在“renderPlot( )”中使用“print( )”,否则坐标会错误。例如,如果您的 UI 中有以下内容:

plotOutput("myplot", click = "myclick")
Run Code Online (Sandbox Code Playgroud)

服务器中的以下内容可以工作:

output$myplot <- renderPlot({
    p = ggplot(data = mtcars, aes(x=mpg, y=hp)) + geom_point()
    p
})
Run Code Online (Sandbox Code Playgroud)

但如果你这样做的话,点击坐标将会是错误的:

output$myplot <- renderPlot({
    p = ggplot(data = mtcars, aes(x=mpg, y=hp)) + geom_point()
    print(p)
})
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过添加到服务器来存储坐标:

mydata = reactiveValues(x_values = c(), y_values = c())

observeEvent(input$myclick, {

    mydata$x_values = c(mydata$x_values, input$myclick$x)
    mydata$y_values = c(mydata$y_values, input$myclick$y)

})
Run Code Online (Sandbox Code Playgroud)

除了 XY 坐标之外,当您在 ggplot2 中使用构面时,您还可以通过以下方式引用单击的构面面板

input$myclick$panelvar1
Run Code Online (Sandbox Code Playgroud)