KGee
KGee

Reputation: 815

Plotly: text is overwritten when traces are added using for loops

I have created a plotly scatter plot which I add traces to using a for loop. When I add text labels or hoverinfo, the text for the last point overwrites all others. Does anyone know how to prevent this?

I have created a reproducible example below where the (correctly named) blue points are created outside the loop however the red points created within the loop have their names overwritten (all incorrectly labelled E as opposed to A->E):

library(plotly)

data.frame1 <- data.frame("name"=paste("name", LETTERS[6:10]), "x"=-1:-5, "y"=-1:-5)
data.frame2 <- data.frame("name"=paste("name", LETTERS[1:5]), "x"=1:5, "y"=1:5)


p <- plot_ly(data.frame1, x = ~x, y = ~y, text = ~paste0(name), 
                         name = "Outside loop", type ="scatter", 
                         mode = "markers+text", marker=list(color="blue") ) 


for(i in 1:nrow(data.frame2)) {
    point <- data.frame2[i, ]
    p <- p %>% add_trace(x = point$x, y = point$y,  text = ~paste0(point$name), 
                                             type ="scatter", mode = "markers+text",
                                             marker = list(color="red", size=10), 
                                             name=point$name )

}

p

enter image description here

Upvotes: 2

Views: 548

Answers (1)

Maximilian Peters
Maximilian Peters

Reputation: 31709

The ~ sign causes the problem, remove in the loop and it should be fine. It makes sense when you refer to your data frame like in the first example but it causes the weird behavior you are observing in the loop.

enter image description here

library(plotly)

data.frame1 <- data.frame("name"=paste("name", LETTERS[6:10]), "x"=-1:-5, "y"=-1:-5)
data.frame2 <- data.frame("name"=paste("name", LETTERS[1:5]), "x"=1:5, "y"=1:5)


p <- plot_ly(data.frame1, x = ~x, y = ~y, text = ~paste0(name), 
             name = "Outside loop", type ="scatter", 
             mode = "markers+text", marker=list(color="blue") ) 

for(i in 1:nrow(data.frame2)) {
  point <- data.frame2[i, ]
  print(paste0(point$name))
  p <- p %>% add_trace(x = point$x, y = point$y,  text = paste0(point$name), 
                       type ="scatter", mode = "markers+text",
                       marker = list(color="red", size=10), 
                       name=point$name )

}

p

Upvotes: 2

Related Questions