R Plotly Bar Chart - 添加水平线标记

R Plotly Bar Chart - Add horizontal line markers

我想绘制一个条形图,每个类别都有两个并排的条形图 (LETTERS),并为每个条形图添加一条水平线(y_ref 为红线 & z_ref 为绿线)。它应该是这样的:

我用 add_trace(和 add_lines、add_segment 等)试过,但找不到正确的方法让它工作。这是我迄今为止尝试过的代表之一。

df <- tibble(x = LETTERS[1:5], y = runif(5), z = runif(5), y_ref = runif(5), z_ref = runif(5))

plot_ly(
  df,
  x = ~x,
  y = ~y,
  type = "bar",
  name = "a"
) %>% add_trace(
  y = ~z, 
  name = "b"
) %>% layout(
  legend = list(
    orientation = "h"
  )
) %>% add_trace(
  y = ~y_ref, 
  type = 'scatter', 
  mode = 'lines',
  marker = list(
    line = list(
      width = 2,
      color = "red"
    )
  )
) %>% add_trace(
  y = ~z_ref, 
  type = 'scatter', 
  mode = 'lines',
  marker = list(
    line = list(
      width = 2,
      color = "green"
    )
  )
)

编辑:我需要 n 个柱的解决方案。

您必须在 Plotly 中对线段使用 shapes。此外,由于 x-axis 是离散的,因此形状的 x 需要在 paper space.

在论文 space 中工作时,您可以使用绘图 domain 计算出 x 的值。对于 xy 轴,Plotly 的默认 domain 设置为 [0, 1]。

条之间有间隙;这也必须考虑在内。我使用了三个函数来创建线段,使用了所有这些信息。

最后,我使用了 seed 来提高可重复性。

文库、种子和基地

library(tidyverse)
library(plotly)

set.seed(8)
df <- tibble(x = LETTERS[1:5], y = runif(5), z = runif(5),
             y_ref = runif(5), z_ref = runif(5))

p = plot_ly(df, x = ~x, y = ~y,
        type = "bar", name = "a") %>% 
  add_trace(y = ~z, name = "b") 

创建细分

# standard shape elements, call for color
details <- function(col){
  list(type = 'line',
       line = list(color = col),
       xref = "paper", yref = "y")
}
# green lines for orange bars
segs = lapply(1:nrow(df),
              function(k){
                x1 <- (k + k)/10 - .02  # if the domain is [0, 1]
                x0 <- x1 - .08
                y0 <- y1 <- df[k, ]$z_ref
                line = list("x0" = x0, "x1" = x1,
                            "y0" = y0, "y1" = y1)
                deets = details("green")
                c(deets, line)
              })
# green lines for blue bars
segs2 = lapply(1:nrow(df),
               function(j){
                 x1 <- (j + j - 1)/10  # if the domain is [0, 1]
                 x0 <- x1 - .08
                 y0 <- y1 <- df[j, ]$y_ref
                 line = list("x0" = x0, "x1" = x1,
                             "y0" = y0, "y1" = y1)
                 deets = details("red")
                 c(deets, line)
               })
segs = append(segs, segs2)

放在一起

p %>% layout(legend = list(orientation = "h"),
             shapes = segs)