Moving from a normal bar chart to a stacked bar on dygraphs
Asked Answered
R

2

6

I've got an xts df of the following format:

structure(c("May 2022", "Jun 2022", "Jul 2022", "Aug 2022", "Sep 2022", 
"Oct 2022", "Nov 2022", "Dec 2022", " 3035.199", " 5500.000", 
"11568.750", " 2510.000", " 6999.999", "21792.149", " 9750.000", 
" 5624.999", " 2250.000", " 4136.975", " 6525.500", " 2771.875", 
" 4637.500", "16273.499", " 6000.000", " 4494.649", " 2500.000", 
"    0.000", " 3029.000", " 2803.500", "    0.000", "14481.250", 
" 4374.998", " 4062.498", "    0.000", " 3075.000", " 6939.249", 
" 1500.000", " 4183.157", " 5769.000", " 3559.500", " 3250.000"
), class = c("xts", "zoo"), index = structure(c(1651363200, 1654041600, 
1656633600, 1659312000, 1661990400, 1664582400, 1667260800, 1669852800
), tzone = "UTC", tclass = "yearmon"), .Dim = c(8L, 5L), .Dimnames = list(
    NULL, c("Month", "Cat 1", "Cat 2", "Cat 3", "Cat 4")))

I'm trying to create a stacked bar chart using the dygraphs library.

library(dygraphs)
library(lubridate)
today <- as.Date(Sys.time())
    last_6 <- today+months(-6)
        dygraph(df) %>%
          dyAxis("y", label= "Total") %>%
          dyRangeSelector(dateWindow = c(last_6, today)) %>%
          dyMultiColumnGroup(c("Cat 1", "Cat 2", "Cat 3", "Cat 4"))

This produce a bar chart that looks like this:Current bar chart

I was wondering if anyone had any advice on how to make stacked bar chart? Many of the guides talk about bringing in plotters, but unfortunately they are not detailed enough for me to properly understand what is going on.

Adding this:

dyStackedBarGroup(c("Cat 1", "Cat 2", "Cat 3", "Cat 4"))

instead of the dyMultiColumnGroup line leads to a:

Error in cumulativeYval + points : non-numeric argument to binary operator
Recusant answered 20/12, 2022 at 15:55 Comment(2)
object 'last_6' not found error when running data and code in question. Do you get this when running the question in a fresh version of R?Conformable
Hi Peter, sorry for that, it should be corrected now (lubridate was needed)Recusant
M
4

While Quinten's got a great working answer, I thought I would add to it.

You don't need separate ts objects; you do need the data to be numeric, though.

Assuming the data from dput is named df:

# drop the months column, change data to numeric, restore ts class
df <- df[ ,-1] %>% sapply(as.numeric) %>%
  ts(start = c(2022, 5), deltat = 1/12)

Now you're ready to graph.

dygraph(df) %>%
  dyAxis("y", label= "Total") %>%
  dyRangeSelector(dateWindow = c(today() - months(6), today())) %>%
  dyStackedBarGroup(dimnames(df)[[2]])

enter image description here

Manometer answered 22/12, 2022 at 19:49 Comment(2)
Thanks for this I think it's almost fixed. Though, it seems the ts object breaks the order of the data (by month), any idea how to get around that?Recusant
Oh man, I figured out what happened. When I first posted this answer, I set the plot range from May to December and realized that wasn't what you were looking for. When I changed the range selector, I changed the start date in the call for ts(). That shouldn't have happened. I've fixed the code now. The only change is in the argument start in the call forts()Manometer
J
4

It seems that you should create each time series as ts, so I convert them each separately and after that combined them with cbind. Here is a reproducible example:

Cat1 <- ts(c(3035.199, 5500.000, 11568.750, 2510.000, 6999.999, 21792.149, 9750.000, 5624.999), start = c(2022, 5), end = c(2022, 12), frequency = 12)
Cat2 <- ts(c(2250.000, 4136.975, 6525.500, 2771.875, 4637.500, 16273.499, 6000.000, 4494.649), start = c(2022, 5), end = c(2022, 12), frequency = 12)
Cat3 <- ts(c(2500.000, 0.000, 3029.000, 2803.500, 0.000, 14481.250, 4374.998, 4062.498), start = c(2022, 5), end = c(2022, 12), frequency = 12)
Cat4 <- ts(c(0.000, 3075.000, 6939.249, 1500.000, 4183.157, 5769.000, 3559.500, 3250.000), start = c(2022, 5), end = c(2022, 12), frequency = 12)

df <- cbind(Cat1, Cat2, Cat3, Cat4)

library(dygraphs)
library(lubridate)

today <- as.Date(Sys.time())
last_6 <- today+months(-6)
dygraph(df) %>%
  dyAxis("y", label= "Total") %>%
  dyRangeSelector(dateWindow = c(last_6, today)) %>%
  dyStackedBarGroup(name = c("Cat1", "Cat2", "Cat3", "Cat4"))

Created on 2022-12-22 with reprex v2.0.2

Jew answered 22/12, 2022 at 18:25 Comment(2)
I should use dygraph more often!Inclinable
Hi @TarJae, Yes interesting package! Although the documentation could be improved.Jew
M
4

While Quinten's got a great working answer, I thought I would add to it.

You don't need separate ts objects; you do need the data to be numeric, though.

Assuming the data from dput is named df:

# drop the months column, change data to numeric, restore ts class
df <- df[ ,-1] %>% sapply(as.numeric) %>%
  ts(start = c(2022, 5), deltat = 1/12)

Now you're ready to graph.

dygraph(df) %>%
  dyAxis("y", label= "Total") %>%
  dyRangeSelector(dateWindow = c(today() - months(6), today())) %>%
  dyStackedBarGroup(dimnames(df)[[2]])

enter image description here

Manometer answered 22/12, 2022 at 19:49 Comment(2)
Thanks for this I think it's almost fixed. Though, it seems the ts object breaks the order of the data (by month), any idea how to get around that?Recusant
Oh man, I figured out what happened. When I first posted this answer, I set the plot range from May to December and realized that wasn't what you were looking for. When I changed the range selector, I changed the start date in the call for ts(). That shouldn't have happened. I've fixed the code now. The only change is in the argument start in the call forts()Manometer

© 2022 - 2024 — McMap. All rights reserved.