Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get equal width bars in a barplot

I have the following data:

dput(test_mod3)

And I draw barplot for it by doing:

ggplot(data=test_mod3, aes(x = as.factor(realDist), y = 1-value, fill=as.factor(clusteringDistance), width=0.75 ) ) + 
  stat_summary( fun.y=mean, geom="bar", width=0.1, color="black", size=0.2, position=position_dodge(width = 0.90) ) +
  stat_summary( fun.data=mean_cl_normal,geom="errorbar", width=0.35, size=0.3, position=position_dodge(width = 0.90)) 

and this gives me the following bars:

enter image description here

I would like to have all the bars in the same size, although there is no bars to plot for the x=100. So the only bar appearing for x=100 should be same width like the other ones

To achieve that I tried something like:

rd_100 <- c(100, 100, 100, 100, 100)
val_100 = c(1,1,1,1,1)
cd_100 = c(200,300,400,500,550)
df_100 = data.frame(rd_100, val_100, cd_100)

names(df_100) <- names(test_mod2) 
test_mod2 <- rbind(test_mod2, df_100)

However this gave me enormous confidence intervals, but the width was OK...

Is there any other way to have equal width bars while using stat_summary()?

like image 398
cross Avatar asked Jul 09 '26 19:07

cross


2 Answers

Instead of summarising inside ggplot2 with stat_summary, we precalculate those values and we will add the missing groups for realDist = 100 as NAs to achieve the same width later.

First, we use dplyr to group the data and summarise by the mean and the lower and upper limits of the population mean using mean_cl_normal.

library(dplyr)
df <- test_mod3 %>% 
      group_by(realDist, clusteringDistance) %>% 
      summarise(mean = mean(value), ymin = mean_cl_normal(value)$ymin,
                ymax = mean_cl_normal(value)$ymax)

Output:

  realDist clusteringDistance      mean      ymin      ymax
1       10                100 0.9997100 0.9996082 0.9998118
2       10                200 0.9963526 0.9959486 0.9967567
3       10                300 0.9860415 0.9850053 0.9870777
4       10                400 0.9711180 0.9695458 0.9726903
5       10                500 0.9496824 0.9471561 0.9522088
6       10                550 0.9632924 0.9606701 0.9659147
7      100                100 0.9877920 0.9867590 0.9888251

Then we take care of the missing groups. We create all the combinations of realDist and clusteringDistance.

df <- rbind(df, cbind(expand.grid(realDist = levels(as.factor(df$realDist)),
           clusteringDistance = levels(as.factor(df$clusteringDistance))),
           mean = NA, ymin = NA, ymax = NA))

Output:

   realDist clusteringDistance      mean      ymin      ymax
1        10                100 0.9997100 0.9996082 0.9998118
2        10                200 0.9963526 0.9959486 0.9967567
3        10                300 0.9860415 0.9850053 0.9870777
4        10                400 0.9711180 0.9695458 0.9726903
5        10                500 0.9496824 0.9471561 0.9522088
6        10                550 0.9632924 0.9606701 0.9659147
7       100                100 0.9877920 0.9867590 0.9888251
8        10                100        NA        NA        NA
9       100                100        NA        NA        NA
10       10                200        NA        NA        NA
11      100                200        NA        NA        NA
12       10                300        NA        NA        NA
13      100                300        NA        NA        NA
14       10                400        NA        NA        NA
15      100                400        NA        NA        NA
16       10                500        NA        NA        NA
17      100                500        NA        NA        NA
18       10                550        NA        NA        NA
19      100                550        NA        NA        NA    

Finally, we plot the data using geom_bar with stat = "identity" and geom_errorbar

ggplot(data=df, aes(x = as.factor(realDist), y = 1-mean, fill=as.factor(clusteringDistance), width=0.75 )) +
      geom_bar(stat = "identity", position=position_dodge(width = 0.90), color="black", size=0.2)+
      geom_errorbar(aes(ymin=1-ymin, ymax=1-ymax), width=.35, size=0.3,  position=position_dodge(.9))

enter image description here

like image 82
mpalanco Avatar answered Jul 13 '26 07:07

mpalanco


You can achieve something close to what you're looking for with faceting:

ggplot(data=test_mod3, aes(x = as.factor(clusteringDistance), y = 1-value, fill=as.factor(clusteringDistance), width=0.75 ) ) + 
  stat_summary( fun.y=mean, geom="bar", width=0.1, color="black", size=0.2, position=position_dodge(width = 0.90) ) +
  stat_summary( fun.data=mean_cl_normal,geom="errorbar", width=0.35, size=0.3, position=position_dodge(width = 0.90)) +
  facet_grid(. ~ realDist)

enter image description here

like image 24
heathobrien Avatar answered Jul 13 '26 08:07

heathobrien



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!