How to build customized Barchart in ggplotly?

Viewed 35

I have bar chart with positive and negative bars. My goal is to do it in ggplotly and fill negative one with white color and keep borders with the same colors.

Code:

df <- data.frame (model = c("A","A","A","A","A","B","B","B","B","B"),
                  size = c("med","big","small","big","small","med","big","small","big","small"),
                  sale = c(1001,1050,-300,-150,-25,960,670,90,-105,-76),
                  area = c("med","large","narrow","large","narrow","med","large","narrow","large","narrow")
                  )



 ggplot() +
  # plot positive with fill and colour based on model
  geom_col(aes(sale, tidytext::reorder_within(size, sale, model),
               fill = size, color = size), 
           data = df,
           position = "stack") + 
  tidytext::scale_y_reordered() +
  labs(fill = "margin2") +
  facet_grid(model ~ ., switch = "y",scales = "free_y") +
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines")) + 
  theme(legend.position="none") + geom_vline(xintercept = 0)

Output Expexcted output:

Expexcted output

1 Answers

You could do a bit of data manipulation and add another layer:

df %>%
  mutate(y = tidytext::reorder_within(size, sale, model)) %>%
  group_by(size, model) %>%
  mutate(sale_neg = sum(sale[sale < 0])) %>%
  ggplot(aes(sale, y, fill = size, color = size)) +
  geom_col(position = "stack") + 
  geom_col(position = 'identity', aes(x = sale_neg), fill = 'white') +
  tidytext::scale_y_reordered() +
  labs(fill = "margin2") +
  facet_grid(model ~ ., switch = "y",scales = "free_y") +
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines")) + 
  theme(legend.position="none") + geom_vline(xintercept = 0)

enter image description here

Related