1

I am trying to adapt this example in Plotly's documentation, in order to show the percentage of answers (Yes/No) to a question, for two classes of people. For example, input data could be:

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

Which would result in something like this. However, the order of the bars is different from the way they were intended to be displayed, given the order in which data is arranged in the vectors y, x1 and x2.

This question mentions a similar problem with bar charts in Plotly, but none of the possible workarounds suggested there seems to make any difference here - I am not sure if it has something to do with the fact that those were vertical, non-stacked bar charts. Besides, I am searching for a solution that do not require the values of x1 and x2 to be known beforehand, as the intention is to generate these charts dynamically.

1 Answers1

0

The important note is that plotly is set to order the plot alphabetically. If you want to change it, just try to change levels of factor. Here's my attempt to ordering the bars in 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

This gives:

The Ordered Horizontal Bar Chart The Usual Plotly Example

TechWizard
  • 346
  • 1
  • 7
  • Using Y-axis as factor did the trick! Also, I haven't noticed that the order of levels was from the bottom of the page upwards, so that Class 2 should come before Class 1. Thanks!! – Bernardo Chrispim Baron Nov 13 '18 at 21:17