Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid bars get wider in grouped plots when there is a missing bar?

Tags:

r

ggplot2

Grouped plots in ggplot show several bars for each value of x because bars are grouped by a third dimension (called fill). When I have no data for a group and value of x the other bars in the group get wider to use all the space. I don't want bars having different widths and I want to preserve the spaces that correspond to the missing bars.

The following is a modified version from the code in https://www.r-graph-gallery.com/265-grouped-boxplot-with-ggplot2.html to illustrate the issue. The difference from the original code is that I removed a boxplot bar in the dataset by filtering out the data where the treatment is "low" and the variety is "D".

# library
library(ggplot2)
library(dplyr)
 
# create a data frame
variety=rep(LETTERS[1:7], each=40)
treatment=rep(c("high","low"),each=20)
note=seq(1:280)+sample(1:150, 280, replace=T)
data=data.frame(variety, treatment ,  note)

# remove data of treatment "low" and variety "D"
data <- filter(data, treatment != "low" | variety != "D")
 
# grouped boxplot
ggplot(data, aes(x=variety, y=note, fill=treatment)) + 
    geom_boxplot()

This code produces the following plot:

enter image description here

The issue is that the bar for variety "D" and treatment "high" gets wider. I don't want this data gets wider, but preserving their original wide and showing no bar in the space where the removed data is supposed to be. How can I do this?

like image 269
Daniel Hernández Avatar asked Nov 28 '25 11:11

Daniel Hernández


1 Answers

This could be achieved with position = position_dodge(preserve = "single"):

# library
library(ggplot2)
library(dplyr)

# create a data frame
variety=rep(LETTERS[1:7], each=40)
treatment=rep(c("high","low"),each=20)
note=seq(1:280)+sample(1:150, 280, replace=T)
data=data.frame(variety, treatment ,  note)

# remove data of treatment "low" and variety "D"
data <- filter(data, treatment != "low" | variety != "D")

# grouped boxplot
ggplot(data, aes(x=variety, y=note, fill=treatment)) + 
  geom_boxplot(position = position_dodge(preserve = "single"))

like image 161
stefan Avatar answered Nov 30 '25 00:11

stefan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!