繁体   English   中英

R:如何在情节中修改图例?

[英]R: How to modify the legend in plotly?

我有 3 个数值变量并通过plot_ly中的条形图绘制它们。 “销售”和“分享”列通过条形显示,而“成本”则通过红线显示。 现在我想稍微自定义一下图例并在图例地图中的成本周围添加黑色边框(见预期结果)

df <- data.frame (model  = c("A", "B", "C","D","E","F"),
                  share = c(12,20,15,9,60,20),
                  sale = c(16,25,18,14,67,28),
                  cost = c(14,19,28,24,57,28))

#set levels of model by cost
df$model <- factor(df$model, levels = arrange(df, desc(df$cost))$model)

library(tidyverse)

df_long <- df %>% 
  pivot_longer(
    cols = -model
  ) 


df_long %>% 
  filter(name != "cost") %>% 
  plot_ly(x = ~model, y = ~value, color = ~name, type = "bar", 
          customdata = ~name,  colors = c("blue", "gray"),
          hovertemplate = paste0("Model: %{x}<br>Value: %{y}<br>",
                                 "Name: %{customdata}<extra></extra>")) %>%
  add_lines(inherit = F, data = df, x = ~model, 
            y = ~cost, color = I("red"),
            name = "cost",
            hovertemplate = paste0("Model: %{x}<br>Value: %{y}<br>",
                                   "Name: cost<extra></extra>")) %>% 
  add_annotations(data = df, x = ~model, y = ~cost, text = ~cost,
                  bgcolor = "white", bordercolor = "black", 
                  xshift = 15, yshift = 15, showarrow = F) %>% 
  layout(barmode = "group")

输出:

在此处输入图像描述

预期输出: 在此处输入图像描述

这个很棘手! 我知道 Plotly 没有任何内置功能可以简单地做到这一点。 我尝试使用形状来绘制这个框,但这不起作用,因为它将图例放在顶部(所以大部分框都被隐藏了)。 不过,我显然比 Plotly 更固执。

这个答案需要包htmlwidgets 我没有改变你的情节,把它分配给一个对象。 我将此答案命名为您的 Plotly 对象pL

onRender函数的内容:

or = ("function(el){
      costLeg = document.querySelectorAll('g.traces')[2];      /* third legend entry */
      cChW = costLeg.firstChild.getBoundingClientRect().width; /* text only */
      cR = costLeg.lastChild.getBoundingClientRect();          /*g trace space*/ 
      cR2 = costLeg.lastChild.outerHTML.split('\" ');
      cy = cR2[3].split('\"')[1];                              /* the y without padding*/
      cDf = cR.width - cChW - 14;                 /*legend width - text width - padding*/
      costLC = costLeg.lastChild.cloneNode(true); /* copy the current rect element */
      costLC.removeAttribute('pointer-events');   /* remove the pointer events */
      costLeg.removeAttribute('class');           /*stop refresh from changing it*/
      costLC.setAttribute('x', 3);                /* calc values + or minus padding */
      costLC.setAttribute('y', (cR.height - 6)/2 * -1); /* measure from center */
      costLC.setAttribute('width', cDf);
      costLC.setAttribute('height', cR.height - 6);
      costLC.setAttribute('style',
          'fill: rgb(0, 0, 0); fill-opacity: 0; stroke-width: 2px; stroke: black;');
      costLeg.insertBefore(costLC, costLeg.lastChild);
      }")

调用绘图并添加onRender函数以绘制框。

pL %>% htmlwidgets::onRender(or)

在此处输入图像描述

顺便说一句,这也应该与你的情节相适应。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM