I am trying to create a barplot that illustrates the number of issue reports for certain issues in an 'imaginary' business. I have used abline() to add a line at a certain value and would like to change the color of the bar above this point. Is such a thing possible to do? Thanks in advance.
My code is as follows:
H<-c(30,35,7,12)
M<-c("Issue 1","Issue 2","Issue 3","Issue 4")
par(mar=c(5,5,5,5))
barplot(H,names.arg=M,ylab="No. of issues",col="light grey",
main="Issue Analysis",border="black",las=2)
abline(h=20,col="red",lty=2)
And the produced graph is:
So, you should see that above the red line is the portion of the first two bars that I want to highlight.
Thanks
CodePudding user response:
You can divide the bars in two parts (some will be zero) and draw them as stacked bars.
Not to have a line between the stacked bars I first draw the stacked bars without borders and then just the border of the original (non-stacked) bars.
h <- 20
H <- c(30, 35, 7, 12)
M <- paste("Issue", seq_along(H))
H2 <- rbind(pmin(H, h), pmax(H-h, 0))
barplot(H2, names.arg=M, ylab="No. of issues", col=gray(c(.7, .8)),
main="Issue Analysis", las=2, border=NA)
barplot(H, col=NA, yaxt='n', add=T)
abline(h=h, col="red", lty=2)
CodePudding user response:
If you want to use ggplot2
, you can use the following function I created (could also use code without function). This is created by slightly modifying the object using ggplot_build
. You can define the "threshold" and "colorbar" you want to give the bar area above the threshold. Here you can see an example with threshold 20 and 10:
H<-c(30,35,7,12)
M<-c("Issue 1","Issue 2","Issue 3","Issue 4")
df <- data.frame(H = H,
M = M)
library(ggplot2)
library(dplyr)
library(tidyr)
threshold_bar <- function(df, threshold, colorbar){
p <- ggplot(df, aes(x = M, y = H))
geom_bar(stat = "identity")
geom_hline(yintercept = threshold, colour = "red")
q <- ggplot_build(p)
q$data[[1]] <- q$data[[1]] %>%
group_by(group) %>%
group_modify(~ add_row(.x, .before = 0)) %>%
fill(everything(), .direction = "up") %>%
mutate(ymin = ifelse(row_number() == 2 & y > threshold, threshold, ymin)) %>%
mutate(fill = case_when(ymin == threshold ~ colorbar,
TRUE ~ fill)) %>%
ungroup()
q <- ggplot_gtable(q)
plot(q)
}
threshold <- 20
colorbar <- "blue"
threshold_bar(df, threshold, colorbar)
threshold <- 10
colorbar <- "blue"
threshold_bar(df, threshold, colorbar)
Created on 2022-08-16 by the reprex package (v2.0.1)
Please note: The function could of course be optimized and extended if you want.