本文介绍了在Plotly R中添加带有选择框角的阴影矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个应用程序,如果用户在Plotly中使用了Box Select工具,那么填充的矩形将出现在Box Select旁边。为了达到这个目的,我试图调用Plotly.addTrace()来创建一个矩形对象(类型:rect),该对象具有用户选择的框的边角。



我能够获得用户所选框(在代码中称为xMin,xMax,yMin和yMax)角落的坐标。但是,我然后尝试创建一个名为drawRect的变量,可以将其添加到Plotly中。虽然这个时候没有做任何事情。



我基于Python Plotly(


I am trying to create an application where if a user employs the Box Select tool in Plotly, then a filled rectangle will appear alongside the Box Select. To accomplish this, I am trying to call Plotly.addTrace() to create a rectangle object (type: rect) that has the corners of the box the user selected.

I am able to obtain the coordinates of the corners of the box the user selected (in the code they are called xMin, xMax, yMin, and yMax). However, I then try to create a variable called drawRect that can be added to Plotly. This does nothing at this time, though.

I based some of the syntax off a post about Python Plotly (https://plot.ly/python/shapes/). However, I am working with Plotly in R. Is there any similar rectangle object that I could use in Plotly R?

Below is MWE showing my code.

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

ui <- basicPage(
  plotlyOutput("plot1")
)

server <- function(input, output) {

  p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(alpha=0) + xlim(0,5) +ylim(-3,3)
  gp <- ggplotly(p)

  set.seed(3)
  myDF <- data.frame(X1=rnorm(10,-1), X2=rnorm(10,-1), X3=rnorm(10,-1), X4=rnorm(10,1), X5=rnorm(10,1), X6=rnorm(10,1))
  colNms <- colnames(myDF)
  nVar <- length(colNms)

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

    var myDF = data.myDF
    var Traces = [];
    var dLength = myDF.length
    var vLength = data.nVar
    var cNames = data.colNms
    for (a=0; a<dLength; a++){
      xArr = [];
      yArr = [];
      for (b=0; b<vLength; b++){
        xArr.push(b)
        yArr.push(myDF[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);

    el.on('plotly_selected', function(e) {
      var dLength = myDF.length
      var selectedPCP = []
      var xMin = e.range.x[0]
      var xMax = e.range.x[1]
      var yMin = e.range.y[0]
      var yMax = e.range.y[1]

      console.log([xMin, xMax, yMin, yMax])

      var Traces = []
      var drawRect = {
        type: 'rect',
        x0: xMin,
        y0: yMin,
        x1: xMax,
        y1: yMax,
        line: {
          color: 'green',
          width: 1
        },
        fillcolor: 'green'
      }
      Traces.push(drawRect);
      Plotly.addTraces(el.id, Traces);
    })
    }", data = list(myDF = myDF, nVar = nVar, colNms = colNms))})

    }
    shinyApp(ui, server)
解决方案

Basically, strange as it may sound to us old ggplot vets, "shapes" are not handled the same way as markers and lines (which are set in "traces"), but "shapes" (like rect) are set in the layout part of a plotly plot. Probably I would understand this better if I read more of the plotly book..

So I made two changes.

  • Changed the dragmode to "select" using layout at the begining.
  • Changed the Plotly.addTraces logic at the end of your onRender javascript to Plotly.relayout

As a sidenote I have been wondering for hours why it was called "relay-out", I just now realized as I was writing this that it is "re-layout" which makes complete sense.

So here is the code:

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

ui <- basicPage(
  plotlyOutput("plot1")
)

server <- function(input, output) {

  p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(alpha=0) + xlim(0,5) +ylim(-3,3)
  gp <- ggplotly(p)

  set.seed(3)
  myDF <- data.frame(X1=rnorm(10,-1), X2=rnorm(10,-1), X3=rnorm(10,-1), X4=rnorm(10,1), X5=rnorm(10,1), X6=rnorm(10,1))
  colNms <- colnames(myDF)
  nVar <- length(colNms)

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

                    var myDF = data.myDF
                    var Traces = [];
                    var dLength = myDF.length
                    var vLength = data.nVar
                    var cNames = data.colNms
                    for (a=0; a<dLength; a++){
                    xArr = [];
                    yArr = [];
                    for (b=0; b<vLength; b++){
                    xArr.push(b)
                    yArr.push(myDF[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);

                    el.on('plotly_selected', function(e) {
                    var dLength = myDF.length
                    var selectedPCP = []
                    var xMin = e.range.x[0]
                    var xMax = e.range.x[1]
                    var yMin = e.range.y[0]
                    var yMax = e.range.y[1]

                    console.log([xMin, xMax, yMin, yMax])

                    var Traces = []
                    var drawRect = {
                    type: 'rect',
                    x0: xMin,
                    y0: yMin,
                    x1: xMax,
                    y1: yMax,
                    line: {
                    color: 'green',
                    width: 1
                    },
                    fillcolor: 'green'
                    }
                    var update = {
                        shapes:[drawRect]
                     }
                    Plotly.relayout(el.id, update)
                    })
                    }", data = list(myDF = myDF, nVar = nVar, colNms = colNms))})

  }
shinyApp(ui, server)

And here is a screen shot of it working:

这篇关于在Plotly R中添加带有选择框角的阴影矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 12:28