0

May I ask you for your help, please? I am trying to make a stacked bar chart with plot_ly() from this dataset: link.

However, it does not result in the desired depiction of the bars. First, I tried just a bar plot with the following line (see left hand chart below):

plotly::plot_ly(df, x=~TimePeriod, y=~round(DataValue_per_GDP*100,2), 
     color=~Sectors, type = "bar") %>% 
     layout(xaxis = list(title = ""), yaxis = list(title = "(% of GDP)"))

But when I try to make this code as a stacked bar chart the data collapse and does not display the time series with negative values, while displaying the time series with values that have opposite sine, see right hand chart below

plotly::plot_ly(df, x=~TimePeriod, y=~round(DataValue_per_GDP*100,2), 
    color=~Sectors, type = "bar") %>% 
    layout(xaxis = list(title = ""), yaxis = list(title = "(% of GDP)"), barmode = 'stack')

What I am doing here in wrong way? I need a stacked bar chart at the end.

enter image description here

Alex
  • 161
  • 6
  • Can you provide your data using `dput(df)` so your code can be [reproduced](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) by others? – jrcalabrese Jan 16 '23 at 18:53
  • Thanks very much for the suggestion! Here is the link to the data produced by the `dput(df)` command: https://github.com/valchyshen/ECON110/blob/main/dput(df) – Alex Jan 16 '23 at 22:44

2 Answers2

1

In barmode = 'stack' the positive and negative values ​​are overlaping each other.

Here is an example dataset:

df <- data.frame(TimePeriod = rep(as.Date(c("2022-01-01", "2022-01-02", 
                                            "2022-01-03", "2022-01-04",
                                            "2022-01-05")), 3),
                 DataValue_per_GDP = c(1, 3, 5, 4,7,
                                       3,-2, 1,-4,0,
                                       2, 3, 2,-1,1),
                 Sectors = rep(c(LETTERS[1:3]), each = 5))

For the date "2022-01-02" we have the following values:

  TimePeriod DataValue_per_GDP Sectors
1 2022-01-02                 3       A
2 2022-01-02                -2       B
3 2022-01-02                 3       C

The first bar A starts at 0 up to 3. The bar B starts at the value 3 and goes two values down to 1. Bar C starts at 1 und goes 3 values up to 4. So the bars overwrite each other and the result looks like this:

enter image description here

To correct this behavior try barmode = 'relative'.

plotly::plot_ly(df, 
                x=~TimePeriod, 
                y=~round(DataValue_per_GDP,2), 
                color=~Sectors, 
                type = "bar") %>% 
  layout(xaxis = list(title = ""), 
         yaxis = list(title = "(% of GDP)"), 
         barmode = 'relative')

enter image description here

tamtam
  • 3,541
  • 1
  • 7
  • 21
  • Thank you very much for your insight! This explains case 100%. And the proposed code has solved my question. – Alex Jan 17 '23 at 12:18
0

After reshaping the data with pivot_wider we could use add_trace with the different columns:

library(plotly)
library(dplyr)
library(tidyr)

df1 <- df %>%
  mutate(Sectors = trimws(Sectors)) %>% 
  pivot_wider(names_from = Sectors, values_from = DataValue_per_GDP) 

fig <- plotly::plot_ly(df1, x=~TimePeriod, y=~round(`C. External`*100,2), 
                type = "bar", name="C. External") %>% 
  add_trace(y = ~`B. Private`, name = 'B. Private') %>% 
  add_trace(y = ~`A. General government`, name = 'A. General government') %>% 
  layout(yaxis = list(title = '(% of GDP)'), barmode = 'stack')
fig

enter image description here

TarJae
  • 72,363
  • 6
  • 19
  • 66