最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to Display a Data Frame as Hover Text in Plotly for R? - Stack Overflow

programmeradmin2浏览0评论

I'm working with Plotly in R and I want to display a small data frame or table in the hover text of my plot.

I tried using HTML-like tags within the hovertemplate, but it seems that Plotly doesn't interpret these tags as expected. Here's a simple example of what I would like to do :

data <- data.frame(
  Category = c("A", "B", "C"),
  Value1 = c(10, 20, 30),
  Value2 = c(40, 50, 60)
)

fig <- plot_ly(data, x = ~Category, y = ~Value1, type = 'bar')

fig <- fig %>% layout(
  hovermode = 'closest',
  hoverlabel = list(
    bgcolor = "white",
    font = list(size = 12)
  )
) %>% 
  add_trace(
    hovertemplate = paste(
      "<b>Category:</b> %{x}<br>",
      "<table>",
      "<tr><td>Value1:</td><td>%{y}</td></tr>",
      "<tr><td>Value2:</td><td>", data$Value2, "</td></tr>",
      "</table>",
      "<extra></extra>"
    )
  )

fig

I'm working with Plotly in R and I want to display a small data frame or table in the hover text of my plot.

I tried using HTML-like tags within the hovertemplate, but it seems that Plotly doesn't interpret these tags as expected. Here's a simple example of what I would like to do :

data <- data.frame(
  Category = c("A", "B", "C"),
  Value1 = c(10, 20, 30),
  Value2 = c(40, 50, 60)
)

fig <- plot_ly(data, x = ~Category, y = ~Value1, type = 'bar')

fig <- fig %>% layout(
  hovermode = 'closest',
  hoverlabel = list(
    bgcolor = "white",
    font = list(size = 12)
  )
) %>% 
  add_trace(
    hovertemplate = paste(
      "<b>Category:</b> %{x}<br>",
      "<table>",
      "<tr><td>Value1:</td><td>%{y}</td></tr>",
      "<tr><td>Value2:</td><td>", data$Value2, "</td></tr>",
      "</table>",
      "<extra></extra>"
    )
  )

fig
Share Improve this question asked Mar 12 at 10:11 Bright381Bright381 331 silver badge7 bronze badges 1
  • I just discovered plotly/dashr but since it is not maintained anymore and their example from the README.md is not even working, I would rather avoid wasting time with it. – Bright381 Commented Mar 12 at 10:54
Add a comment  | 

1 Answer 1

Reset to default 2

Pltoly does not allow all HTML elements in the hovertemplate (only br). I can show you two ways to still show tables as hover info. The first one is really easy:

1 Faking a table using hovertext

Since your HTML table is so simplistic, you could fake it by using <b> + </b> + spacing

custom_hover <- paste0(
  "<b>Category:</b> ", data$Category, "<br>",
  "<b>Value1:</b> ", data$Value1, "<br>",
  "<b>Value2:</b> ", data$Value2
)

plot_ly(data, x = ~Category, y = ~Value1, type = 'bar',
               hoverinfo = 'text',
               hovertext = custom_hover) %>%
  layout(
    hovermode = 'closest',
    hoverlabel = list(
      bgcolor = "white",
      font = list(size = 12)
    )
  )

giving

2 Doing the overly complicated way using HTML / JS

If you use htmlwidgets::onRender(js_code) with plotly you can execute your own JavaScript inlcuding plotlys's hover / unhover events. This then can be used to show / hide our own tooltip as per my answer here. The data is passed to Javascript using jsonlite::toJSON(data) and used there to display a custom table. In this solution you can go nuts with CSS / HTML and pretty much customize the whole tooltip.

library(plotly)
library(htmlwidgets)

data <- data.frame(
  Category = c("A", "B", "C"),
  Value1 = c(10, 20, 30),
  Value2 = c(40, 50, 60)
)

js_code <- paste0('
function(el, x) {
  // Parse data to access in JavaScript
  var data = ', jsonlite::toJSON(data), ';
  
  // Create tooltip element
  var tooltip = document.createElement("div");
  tooltip.style.display = "none";
  tooltip.style.position = "absolute";
  tooltip.style.backgroundColor = "white";
  tooltip.style.border = "1px solid #ddd";
  tooltip.style.color = "black";
  tooltip.style.padding = "8px";
  tooltip.style.borderRadius = "4px";
  tooltip.style.zIndex = "1000";
  tooltip.style.boxShadow = "2px 2px 6px rgba(0,0,0,0.2)";
  tooltip.style.fontFamily = "Arial, sans-serif";
  document.body.appendChild(tooltip);
  
  el.on("plotly_hover", function(e) {
    var pt = e.points[0];
    var category = pt.x;
    var value1 = pt.y; // the hover event gives us the x / y value
    
    // Find matching data row
    var row = data.find(d => d.Category === category);
    var value2 = row ? row.Value2 : "N/A"; // mathc for the value2 using data
    
    
    tooltip.innerHTML = ` 
      <div style="font-weight:bold; margin-bottom:6px">Category: ${category}</div> 
      <table style="width:100%; border-collapse: collapse; border: 1px solid black;">
        <tr>
          <th style="border: 1px solid black; padding: 5px;">Name</th>
          <th style="border: 1px solid black; padding: 5px;">Value</th>
        </tr>
        <tr>
          <td style="padding:3px; font-weight:bold; border: 1px solid black;">Value1:</td>
          <td style="padding:3px; text-align:right; border: 1px solid black;">${value1}</td>
        </tr>
        <tr>
          <td style="padding:3px; font-weight:bold; border: 1px solid black;">Value2:</td>
          <td style="padding:3px; text-align:right; border: 1px solid black;">${value2}</td>
        </tr>
      </table>
    `;
    
    tooltip.style.display = "block";
    tooltip.style.left = (e.event.pageX + 10) + "px";
    tooltip.style.top = (e.event.pageY + 10) + "px";
  });
  
  el.on("plotly_unhover", function(e) {
    tooltip.style.display = "none";
  });
}
')

plot_ly(data, x = ~Category, y = ~Value1, type = 'bar') %>% 
  layout(
    hovermode = 'closest',
    hoverlabel = list(enabled = FALSE)  # Disable default hover label
  ) %>%
  config(displayModeBar = TRUE) %>%
  htmlwidgets::onRender(js_code)
发布评论

评论列表(0)

  1. 暂无评论