0

I am trying to generate a barplot with dual Y-axis and error bars. I have successfully generated a plot with error bars for one variable but I don't know how to add error bars for another one. My code looks like this. Thanks.

library(ggplot2)


#Data generation
Year <- c(2014, 2015, 2016)
Response <- c(1000, 1100, 1200)
Rate <- c(0.75, 0.42, 0.80)
sd1<- c(75, 100, 180)
sd2<- c(75, 100, 180)

df <- data.frame(Year, Response, Rate,sd1,sd2)
df



# The errorbars overlapped, so use position_dodge to move them horizontally
pd <- position_dodge(0.7) # move them .05 to the left and right


png("test.png", units="in", family="Times",  width=2, height=2.5, res=300) #pointsize is font size| increase image size to see the key
ggplot(df)  + 
  geom_bar(aes(x=Year, y=Response),stat="identity", fill="tan1", colour="black")+
  geom_errorbar(aes(x=Year, y=Response, ymin=Response-sd1, ymax=Response+sd1),
                width=.2,  # Width of the error bars
                position=pd)+
 geom_line(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'red', size = 2)+
 geom_point(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'black',size = 3)+
 scale_y_continuous(name = "Left Y axis", expand=c(0,0),limits = c(0, 1500),breaks = seq(0, 1500, by=500),sec.axis = sec_axis(~./max(df$Response),name = "Right Y axis"))+
  theme(
    axis.title.y = element_text(color = "black"),
    axis.title.y.right = element_text(color = "blue"))+
  theme(
    axis.text=element_text(size=6, color = "black",family="Times"),
    axis.title=element_text(size=7,face="bold", color = "black"),
    plot.title = element_text(color="black", size=5, face="bold.italic",hjust = 0.5,margin=margin(b = 5, unit = "pt")))+
  theme(axis.text.x = element_text(angle = 360, hjust = 0.5, vjust = 1.2,color = "black" ))+
  theme(axis.line = element_line(size = 0.2, color = "black"),axis.ticks = element_line(colour = "black", size = 0.2))+
  theme(axis.ticks.length = unit(0.04, "cm"))+
  theme(plot.margin=unit(c(1,0.1,0.1,0.4),"mm"))+
  theme(axis.title.y = element_text(margin = margin(t = 0, r = 4, b = 0, l = 0)))+
  theme(axis.title.x = element_text(margin = margin(t = 0, r = 4, b = 2, l = 0)))+
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.background = element_blank())+
  ggtitle("SRG3")+
  theme(legend.position="top")+
  theme(  legend.text=element_text(size=4),
          #legend.justification=c(2.5,1),
          legend.key = element_rect(size = 1.5),
          legend.key.size = unit(0.3, 'lines'),
          legend.position=c(0.79, .8),  #width and height
          legend.direction = "horizontal",
          legend.title=element_blank())

dev.off()

and my plot is as follows:

enter image description here

1 Answer 1

1

A suggestion for future questions: your example is far from being a minimal reproducible example. All the visuals an the annotations are not related to your problem but render the code overly complex which makes it harder for others to work with it.

The following would be sufficient:

ggplot(df) + 
geom_bar(aes(x = Year, y = Response), 
             stat = "identity", fill = "tan1", 
             colour = "black") +
geom_errorbar(aes(x = Year, ymin = Response - sd1, ymax = Response + sd1),
              width = .2,
              position = pd) +
geom_line(aes(x = Year, y = Rate * max(df$Response)), 
          color = 'red', size = 2) +
geom_point(aes(x = Year, y = Rate * max(df$Response)), 
           color = 'black', size = 3)

(Notice that I've removed stat = "identity" in all geom_s because this is set by default. Furthermore, y is not a valid aestetic for geom_errorbar() so I omitted that, too.)

Assuming that the additional variable you would like to plot error bars for is Rate * max(df$Response)) and that the relevant standard deviation is sd2, you may simply append

 + geom_errorbar(aes(x = Year, ymin = Rate * max(df$Response) - sd2, 
                     ymax = Rate * max(df$Response) + sd2), 
                 colour = "green",
                 width = .2)

to the code chunk above. This yields the output below.

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. Right y-axis is missing from your plot
You are welcome. Sorry, I forgot about that: it is not possible add a second Y-axis here since Rate * max(df$Response) is not a monotonic transformation of Response, see ggplot2.tidyverse.org/reference/sec_axis.html.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.