[英]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.