I am trying to change the order and colour of stacked bars in a highcharter plot in R.
I've been used to defining the factor levels when I come up against this issue in ggplot, and when searching for a solution in highcharter have found a few answers advising to similarly define the categories in hc_xAxis(), but this hasn't worked for me. Trying to do so plays havoc with my x-axis (no longer shows it as a date) and it still doesn't change the order. I have also had no joy in specifying the colours of the individual stacked bars, I'm used to doing this using scale_fill_manual() in ggplot, but here it looks like colours are being mapped alphabetically.
My goal is to get the stacked bar order as follows (from bottom to top): TL > WB > PB > UB > NACx > ACx.
Here's my dataframe:
df <- structure(list(Week = structure(c(19478, 19478, 19478, 19478,
19478, 19478, 19478, 19485, 19485, 19485, 19485, 19485, 19485,
19485, 19492, 19492, 19492, 19492, 19492, 19492, 19492, 19499,
19499, 19499, 19499, 19499, 19499, 19499, 19506, 19506, 19506,
19506, 19506, 19506, 19506, 19513, 19513, 19513, 19513, 19513,
19513, 19513), class = "Date"), Status = c("ACx", "NACx", "PB",
"Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL",
"UB", "WB", "ACx", "NACx", "PB", "Plan", "TL", "UB", "WB", "ACx",
"NACx", "PB", "Plan", "TL", "UB", "WB", "ACx", "NACx", "PB",
"Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL",
"UB", "WB"), Units = c(0, 7.13, 46.49, 298.03, 48.11, 20.25,
166.12, 0, 12.87, 67, 298.03, 47, 38, 126.26, 0, 9, 66.27, 328.37,
53.25, 90.25, 98.62, 0, 9.25, 53.13, 355.89, 53.11, 180.5, 45.13,
4, 2.88, 0, 269.55, 6, 169.5, 0, 0, 0, 0, 355.89, 0, 0, 0)), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -42L), groups = structure(list(
Week = structure(c(19478, 19485, 19492, 19499, 19506, 19513
), class = "Date"), .rows = structure(list(1:7, 8:14, 15:21,
22:28, 29:35, 36:42), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -6L), .drop = TRUE))
... and the plot:
highchart() %>%
hc_add_series(subset(df, Status == "Plan"), "column", grouping = FALSE, stack = "Plan",
color = 'rgba(255, 255, 255, 0)', borderColor = "black",
hcaes(x = Week, y = round(Units, digits = 1), group = Status)) %>%
hc_add_series(subset(df, Status != "Plan"), type = 'column', grouping = FALSE, stack = "Activity",
borderColor = "black", color = cols,
hcaes(y = Units, group=Status, x = Week)) %>%
hc_chart(plotBackgroundColor = "#F5F5F5") %>%
hc_plotOptions(series = list(stacking = "normal")) %>%
hc_xAxis(dateTimeLabelFormats = list(week = '%d-%b'), type = "datetime",
title = list(text = "Week Commencing"), gridLineWidth = 1, tickInterval = 604800000) %>%
hc_yAxis(title = list(text = "Activity)"))
cols <- c("ACx" = "#311432",
"NACx" = "#a1045a",
"WB" = "forestgreen",
"TL" = "#D3D3D3",
"PB" = "goldenrod",
"UB" = "#bc544b")
Really appreciate any help.
One option would be to convert Status
to a factor
with the levels set in your desired order. Afterwards you could reorder your colors according to this order as well.
library(highcharter)
levels <- c("TL","WB", "PB", "UB", "NACx", "ACx", "Plan")
df$Status <- factor(df$Status, rev(levels))
cols <- cols[levels(df$Status)]
cols <- cols[!is.na(names(cols))]
highchart() %>%
hc_add_series(subset(df, Status == "Plan"), "column",
grouping = FALSE, stack = "Plan",
color = "rgba(255, 255, 255, 0)", borderColor = "black",
hcaes(x = Week, y = round(Units, digits = 1), group = Status)
) %>%
hc_add_series(subset(df, Status != "Plan"),
type = "column", grouping = FALSE, stack = "Activity",
borderColor = "black", color = cols,
hcaes(y = Units, group = Status, x = Week)
) %>%
hc_chart(plotBackgroundColor = "#F5F5F5") %>%
hc_plotOptions(series = list(stacking = "normal")) %>%
hc_xAxis(
dateTimeLabelFormats = list(week = "%d-%b"), type = "datetime",
title = list(text = "Week Commencing"), gridLineWidth = 1, tickInterval = 604800000
) %>%
hc_yAxis(title = list(text = "Activity)"))