Search code examples
eclipsercran

use crossbar ggplot2


I am plotting bar charts for climate different models. I would like make a plot comparing models to observations. The climate models will plotted as bar (geom_bar()) but I would like to have the observation crossbars.

The script below makes a plot but there is something (upside down triangle) that is plotted above the graph. What is wrong with this script?, Am I missing something?

ch<-structure(list(Month = structure(c(4L, 5L, 6L, 7L, 8L, 9L, 10L, 
11L, 12L, 1L, 2L, 3L), .Label = c("Oct", "Nov", "Dec", "Jan", 
"Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"), class = c("ordered", 
"factor")), GCM1 = c(169.5, 157.19, 90.07, 42.97, 13.24, 1.56, 
2.53, 5.99, 14.92, 46.35, 88.23, 138.02), GCM2 = c(215.01, 193.37, 
131.14, 41.48, 7.63, 0.94, 0.81, 0.78, 1.88, 15.95, 99.58, 188.16
), GCM3 = c(164.83, 158.82, 97.5, 29.27, 5.47, 2.14, 3.34, 0.85, 
9.94, 16.9, 57.21, 117.05), OBS = c(142.25, 138.59, 59.95, 26.48, 
2.61, 0.2, 0.1, 0.4, 0.72, 11.64, 38.75, 119.82)), .Names = c("Month", 
"GCM1", "GCM2", "GCM3", "OBS"), row.names = c(NA, -12L), class = "data.frame")

ch$Month<-month.abb
ch$Month<-factor(ch$Month, levels=c(month.abb[10:12],month.abb[1:9]), ordered=TRUE)

chm<-melt(ch, id="Month")

cbPalette1 <- cbbPalette <- c("#D55E00", "#56B4E9", "#009E73","#0072B2", "#CC79A7","#000000")

p<-ggplot(data=chm,aes(x=factor(Month),y=value,group=variable,fill=variable))+geom_bar(subset = .(variable != "OBS"),stat="identity",position=position_dodge())+
                scale_fill_manual(values=cbPalette1)+
                geom_crossbar(subset = .(variable == "OBS"),aes(ymin = min(value), ymax = max(value)), col="gray30",fatten=3)

.......

Many thanks in advance

BHH


Solution

  • Two things:

    1. You are overriding the group aesthetic to just be variable, so in the crossbar, it is ignoring the different x values (treating it as continuous) and that is giving a weird crossbar.

    2. I think you just want the bar itself, not any extent around it. If so, you want to set ymin and ymax to the central value, not to the range of all central values.

    Making both those changes:

    p<-ggplot(data=chm,
              aes(x = Month,
                  y = value,
                  fill = variable)) +
      geom_bar(subset = .(variable != "OBS"), 
               stat="identity",
               position=position_dodge()) +
      scale_fill_manual(values=cbPalette1)+
      geom_crossbar(subset = .(variable == "OBS"),
                    aes(ymin = value, ymax = value), 
                    col="gray30", fatten=3)
    

    enter image description here