我有 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")
輸出:

預期輸出:

uj5u.com熱心網友回復:
這個很棘手!我知道 Plotly 沒有任何內置功能可以簡單地做到這一點。我嘗試使用形狀來繪制這個框,但這不起作用,因為它將圖例放在頂部(所以大部分框都被隱藏了)。不過,我顯然比 Plotly 更固執。
這個答案需要 package 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);
}")
呼叫 plot 并添加onRender函式來繪制框。
pL %>% htmlwidgets::onRender(or)

順便說一句,這也應該與你的情節相適應。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/493123.html
標籤:r ggplot2 情节地 tidyverse 数据可视化
下一篇:Rshiny中的回應式資料框
