'Create Percentage Change Labels Barplot

I am trying to create a barchart which shows percentage change between the bars for each category of performance test (smallpt,compress etc)

Current Graph Example:

enter image description here

Data:

CG2400Host <- data.frame(
  smallpt = c(38.934),
  compress = c(58.036),
  ffte = c(5629.20),
  johntheripper = c(8067),
  mtdgemm = c(2.043463),
  stockfish = c(16746109),
  streamCopy = c(83562.0),
  streamScale = c(79536.7),
  streamTriad = c(82708.4),
  streamAdd = c(83041.6),
  dbenchOneClient = c(579.090),
  dbenchSixClient = c(2814.47),
  dbenchTwelveClient = c(4141.33),
  dbenchFortyEight = c(4044.82),
  dbenchOneHundredTwentyEight = c(851.355),
  dbenchTwoHundredFiftyEight = c(870.838)
)

CG2300Host <- data.frame(
  smallpt = c(19.712),
  compress = c(52.873),
  ffte = c(4626.09),
  johntheripper = c(8729),
  mtdgemm = c(5.494281),
  stockfish = c(17610837),
  streamCopy = c(79427.8),
  streamScale = c(60582.3),
  streamTriad = c(69226.6),
  streamAdd = c(67805.7),
  dbenchOneClient = c(47.8331),
  dbenchSixClient = c(67.661),
  dbenchTwelveClient = c(82.4374),
  dbenchFortyEight = c(109.27),
  dbenchOneHundredTwentyEight = c(111.981),
  dbenchTwoHundredFiftyEight = c(95.2279)
)

GB1UHost <- data.frame(
  smallpt = c(17.530),
  compress = c(44.628),
  ffte = c(7365.97),
  johntheripper = c(11684),
  mtdgemm = c(1.161368),
  stockfish = c(22878029),
  streamCopy = c(44096.4),
  streamScale = c(29866.3),
  streamTriad = c(31804.6),
  streamAdd = c(31796.5),
  dbenchOneClient = c(755.644),
  dbenchSixClient = c(3333.72),
  dbenchTwelveClient = c(4497.29),
  dbenchFortyEight = c(3510.50),
  dbenchOneHundredTwentyEight = c(2092.10),
  dbenchTwoHundredFiftyEight = c(1720.72)
)

DellHost <- data.frame(
  smallpt = c(19.081),
  compress = c(38.394),
  ffte = c(8569.61),
  johntheripper = c(13365),
  mtdgemm = c(1.791839),
  stockfish = c(22134688),
  streamCopy = c(133314.5),
  streamScale = c(89241.6),
  streamTriad = c(94915.5),
  streamAdd = c(93186.8),
  dbenchOneClient = c(852.674),
  dbenchSixClient = c(3369.59),
  dbenchTwelveClient = c(4348.31),
  dbenchFortyEight = c(1497.37),
  dbenchOneHundredTwentyEight = c(1528.85),
  dbenchTwoHundredFiftyEight = c(1505.47)
)

Current code:

createHostComparisonBarchart <- function(CG2300DF,CG2400DF,GB1UDF,DellDF){
  BarChartNames<-c("Smallpt Barchart","Compressed G-Zip","FFTE","John The Ripper","Mt-dgemm","Stockfish","Stream - Copy",
                   "Stream - Scale","Stream - Triad","Stream - Add","Dbench 1 Client","Dbench 6 Client","Dbench 12 Client",
                   "Dbench 48 Client","Dbench 128 Client","Dbench 256 Client")
  UnitNames <- c("seconds","seconds","MFLOPS/s","Crypts/s","MFLOPS/s","Nodes/s","MB/s","MB/s","MB/s","MB/s","MB/s","MB/s",
                 "MB/s","MB/s","MB/s","MB/s")
  IndexNames <- c("smallpt","compress","ffte","johntheripper","mtdgemm","stockfish","streamCopy","streamScale","streamTriad",
                  "streamAdd","dbenchOneClient","dbenchSixClient","dbenchTwelveClient","dbenchFortyEight","dbenchOneHundredTwentyEight",
                  "dbenchTwoHundredFiftyEight")
  
  for (i in 1:length(BarChartNames)){
    values <- data.frame(
      serverType <- c("CG2300","CG2400","GB1U","R6525 Dell"),
      result <- c(CG2300DF[i],CG2400DF[i],GB1UDF[i],DellDF[i])
    )
    p<-ggplot(data=values, aes(x=serverType, y=result,fill=serverType)) +
      geom_bar(stat="identity")+theme_minimal()+
      xlab("Server Type")+
      ylab(UnitNames[i])+
      ggtitle(BarChartNames[i])
    print(p)
  }
}

I have a function for calculating the percentage change between the values:

percentageChangeCalc <-function(serverADF,serverBDF){
  percentChange <-c()
  for (i in 1:length(colnames(serverADF))){
    val <- (serverBDF[i] - serverADF[i])/ serverADF[i]
    percentChange <- append(percentChange,val)
    
  }
  percentChange
}

Since each "bar" in the chart is compared to the one next to it...

percentageChangeCalc(CG2300Host,CG2400Host)
percentageChangeCalc(CG400Host,GB1UHost)
percentageChangeCalc(GB1UHost,DellHost)

would work.

I have tried different iterations of implementing this from using geom_text to geom_label but I seem to keep getting Error: Discrete value supplied to continuous scale. This makes me think it is not possible to carry out this with my current data.

I am aiming for something like:

enter image description here

Any help appreciated.



Solution 1:[1]

Maybe this helps:

library(tidyverse)
set.seed(1337)
data <- tibble(year = seq(2014, 2019), value = rpois(6, lambda = 10))
data
#> # A tibble: 6 × 2
#>    year value
#>   <int> <int>
#> 1  2014    10
#> 2  2015     5
#> 3  2016     8
#> 4  2017     8
#> 5  2018     6
#> 6  2019    12

data %>%
  mutate(
    diff = dplyr::lead(value) - value,
    label_y = value %>% map2_dbl(diff, ~ 1.1 * max(.x, .x + .y))
  ) %>%
  ggplot(aes(year)) +
  geom_col(aes(y = value)) +
  geom_errorbar(aes(ymin = value, ymax = value + diff), color = "red", width = 0.3) +
  geom_label(aes(y = label_y, label = diff), color = "red")
#> Warning: Removed 1 rows containing missing values (geom_label).

Created on 2022-02-22 by the reprex package (v2.0.0)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 danlooo