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 thelayout
part of a plotly plot. Probably I would understand this better if I read more of the plotly book..So I made two changes.
dragmode
to"select"
usinglayout
at the begining.Plotly.addTraces
logic at the end of youronRender
javascript toPlotly.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:
And here is a screen shot of it working: