Introduction

Creating a Waterfall chart in R GGPLOt.

Video link https://youtu.be/7dw-icBEQ0I

Packages used

#install.packages("waterfalls")
library(waterfalls)
library(ggplot2)
library(stringr)

Sample data

dt <- data.frame(funding = c('Monthly Income'
                             , 'Shares Income' 
                             , 'Fixed Deposit Income'
                             , 'Rental Expenses'
                             , 'Grocery expense'
                             , 'Other expense')
                 , Amounts = c(100000
                               , 20000
                               , 15000
                               , -30000
                               , -15000
                               , -10000)
)

dt
FALSE                funding Amounts
FALSE 1       Monthly Income  100000
FALSE 2        Shares Income   20000
FALSE 3 Fixed Deposit Income   15000
FALSE 4      Rental Expenses  -30000
FALSE 5      Grocery expense  -15000
FALSE 6        Other expense  -10000

First chart

Using the waterfall package lets run the first chart. In all simplicity if we had only two columns in the data then the numeric column is used for values and the character or factor column will be used for defining the labels.

waterfall( dt)

# Equivalent to:
#waterfall(values = value, labels = group)

Second chart

Notice that the scientific notation was displayed in the above chart, which we don’t want. So we can fix it by using the scipen(options = 999)

options(scipen = 999)
waterfall( dt)

Third chart

Now for the serious stuff, we will customise the charts using the ggplot commands. The waterfall chart is a ggplot object so any ggplot command can be used.

pl <- waterfall(dt
                , calc_total = TRUE
                , rect_width = 0.4
                , draw_lines = TRUE
                , linetype = 2
                , fill_by_sign = TRUE
                , fill_colours = c("steelblue","green","yellow","Red","Pink","grey92", "white")
                , total_rect_color = "grey"
                , total_rect_text_color = "red"
                , rect_border = NA)

pl <- pl + theme_classic()
pl <- pl +  labs(title="Water fall chart")
pl <- pl +  labs(subtitle="  showing monthly household cashflow")
pl <- pl +  labs(caption="@technanswers88 on YouTube")
pl <- pl + labs(x = '', y = '')
pl

Another variation

Showing a horizontal line to indicate the total remaining.

library(ggplot2)
library(forcats)

dt2 <- data.frame(funding = c('Opening Balance'
                              , 'Fixed Costs' 
                              , 'Variable Costs'
                              , 'Salaries'
                              , 'Other expense')
                  , Amounts = c(100000
                                , -20000
                                , -15000
                                , -30000
                                , -10000
                  )
)



dt2 <- dt2%>%
  dplyr::mutate(balance = Amounts - lag(Amounts))

dt2$funding <- as.factor(dt2$funding)

dt2$funding <- forcats::fct_relevel(dt2$funding,  c('Opening Balance'
                                     , 'Fixed Costs' 
                                     , 'Variable Costs'
                                     , 'Salaries'
                                     , 'Other expense'))
dt2$id <- seq_along(dt2$Amounts)
dt2$type <- ifelse(dt2$Amounts > 0, "in","out")
dt2$end <- cumsum(dt2$Amounts)
dt2$start <- c(0,head(dt2$end, -1))


pl <- ggplot(data = dt2, aes(x = funding, fill = type))
pl <- pl + geom_rect( aes(x = funding
                          ,xmin = id - 0.45
                     , xmax = id + 0.45
                     , ymin = end
                     , ymax = start))
pl <- pl + theme_bw()
pl <- pl + geom_text(aes(x = funding
                         , y = (start+ end) /2
                         , label = paste(stringr::str_wrap(funding, 5) 
                                         , "\n"
                                         ,scales::comma(Amounts))))
                     
pl <- pl + geom_hline(yintercept = tail(dt2$end,1)  )                     
pl <- pl + scale_fill_manual(values = c("green","red"))
pl <- pl +  labs(title="Water fall chart")
pl <- pl +  labs(subtitle="  showing monthly household cashflow")
pl <- pl +  labs(caption="@technanswers88 on YouTube")
pl <- pl + labs(x = '', y = '')
pl

Video link https://youtu.be/7dw-icBEQ0I