Search code examples
rplotly

Why is hovertemplate not showing up correctly for some data points for plotly in R


mydat2 <- data.frame(subject = c("math", "english", "chemistry"), score = c(80, 50, 65), class = c("A", "B", "A"), count = c(50, 60, 70))

library(plotly)
plot_ly(data = mydat2,
        x = ~score,
        y = ~count,
        color = ~class,
        customdata= ~class,
        hoverinfo = 'text',
        text = ~subject,
        hovertemplate = paste(
           "<b>%{text}</b><br><br>",
           "%{yaxis.title.text}: %{y:,.0f}<br>",
           "%{xaxis.title.text}: %{x:,.0f}<br>",
           "Class: %{customdata}",
           "<extra></extra>"
        ))

enter image description here

I'm confused as to why the hover for the left most point shows up as %{text} instead of english. The hover labels for the other 2 points on the plot are perfectly fine.


Solution

  • Here is your graph, with the hover template that you're looking for. The explanation follows.

    plot_ly(data = mydat2,
            x = ~score,
            y = ~count,
            color = ~class,
            type = "scatter",
            mode = "markers",
            customdata= ~class,
            hoverinfo = 'text',
            text = ~I(subject),         # <---- I changed!!
            hovertemplate = paste(
              "<b>%{text}</b><br><br>",
              "%{yaxis.title.text}: %{y:,.0f}<br>",
              "%{xaxis.title.text}: %{x:,.0f}<br>",
              "Class: %{customdata}",
              "<extra></extra>"
            ))
    

    enter image description here

    I've seen this problem before. I've usually come up with a workaround, but never really figured out what went wrong until now. I found a closed ticket on GitHub for this issue (closed in 2019). (Ah, ya... so not fixed.) Apparently, it has to do with using color.

    However, the bright spot...for a hot minute someone actually believed it was a problem and came up with a fix. @cpsievert wrote a bit of code that includes an lapply call (towards the middle of the page, if you visit the site). When I investigated what the code did, I realized it could be a lot simpler (and it was pretty simple, to begin with).

    That ticket on GitHub is here if you wanted to check that out.

    This is the code the maintainer provided (that you don't actually need).

    l <- plotly_build(p)$x
    l$data <- lapply(l$data, function(tr) { tr[["text"]] <- I(tr[["text"]]); tr })
    as_widget(l)
    

    The fix is the function I(). Instead of hovertext = or text = ~subject, you need hovertext = or text = ~I(subject). <-- note the I()