Plotly 水平条形图中的排序列

Ordering columns in Plotly horizontal bar chart

我正在尝试调整 Plotly 文档中的 this example,以便显示两个 类 人对一个问题的回答百分比 (Yes/No)。例如,输入数据可以是:

x1 <- c(62.7, 89.2) # answered yes; can change, as values come from another function
x2 <- sapply(x1, function(x) 100-x) # answered no
y <- c("Class1", "Class2")
data <- data.frame(y, x1, x2)

library(plotly)
# ...generate chart according to example Plotly's in documentation

这会导致 something like this。但是,考虑到数据在向量 y、x1 和 x2 中的排列顺序,条形图的顺序与它们的预期显示方式不同。

在 Plotly 中提到了条形图的类似问题,但是 none 可能的解决方法表明这里似乎有任何不同 - 我不确定它是否与事实上,那些是垂直的,非堆叠条形图。此外,我正在寻找一种不需要事先知道 x1 和 x2 值的解决方案,因为目的是动态生成这些图表。

重要说明是 plotly 设置为按字母顺序排列情节。如果您想更改它,只需尝试更改因子水平即可。这是我在 plotly 中对条形图进行排序的尝试。

x1 <- c(62.7, 89.2) # answered yes; can change, as values come from another function
x2 <- sapply(x1, function(x) 100-x) # answered no
y <- c("Class1", "Class2")
data <- data.frame(y, x1, x2)
# ------------------------------------------------
# PLEASE PROVIDE THE ORDER OF CLASSES HERE
# ------------------------------------------------
data$y <- factor(data$y, levels = c("Class2", "Class1")) 

library(plotly)

top_labels <- c('Yes', 'No')

p <- plot_ly(data, 
             x = ~x1, 
             y = ~y, 
             type = 'bar', 
             orientation = 'h',
             marker = list(color = 'rgba(38, 24, 74, 0.8)',
                           line = list(color = 'rgb(248, 248, 249)', width = 1))) %>%
  add_trace(x = ~x2, marker = list(color = 'rgba(71, 58, 131, 0.8)')) %>%
  layout(xaxis = list(title = "",
                      showgrid = TRUE,
                      showline = FALSE,
                      showticklabels = FALSE,
                      zeroline = FALSE,
                      domain = c(0.15, 1)),
         yaxis = list(title = "",
                      showgrid = FALSE,
                      showline = FALSE,
                      showticklabels = FALSE,
                      zeroline = FALSE),
         barmode = 'stack',
         paper_bgcolor = 'rgb(248, 248, 255)', 
         plot_bgcolor = 'rgb(248, 248, 255)',
         margin = list(l = 120, r = 10, t = 140, b = 80),
         showlegend = FALSE) %>%
  # labeling the y-axis
  add_annotations(xref = 'paper', 
                  yref = 'y', 
                  x = 0.14, 
                  y = y,
                  xanchor = 'right',
                  text = y,
                  font = list(family = 'Arial', size = 12,
                              color = 'rgb(67, 67, 67)'),
                  showarrow = FALSE, align = 'right') %>%

  # labeling the percentages of each bar (x_axis)
  add_annotations(xref = 'x', yref = 'y',
                  x = x1 / 2, y = y,
                  text = paste(data[,"x1"], '%'),
                  font = list(family = 'Arial', size = 12,
                              color = 'rgb(248, 248, 255)'),
                  showarrow = FALSE) %>%
  add_annotations(xref = 'x', yref = 'y',
                  x = x1 + x2 / 2, y = y,
                  text = paste(data[,"x2"], '%'),
                  font = list(family = 'Arial', size = 12,
                              color = 'rgb(248, 248, 255)'),
                  showarrow = FALSE) %>% 
  # labeling the first Likert scale (on the top)
  add_annotations(xref = 'x', yref = 'paper',
                  x = c(21 / 2, 21 +  120/ 2),
                  y = 1.10,
                  text = top_labels,
                  font = list(family = 'Arial', size = 12,
                              color = 'rgb(67, 67, 67)'),
                  showarrow = TRUE)

p

这给出: