2
votes

I have a plot using ggplot, and I would like to add points and error bars to it. I am using geom_errorbar and geom_point, but I am getting an error: "Discrete value supplied to continuous scale" and I am not sure why. The data labels in the plot below should remain the same. I simply want to add new points to the existing graph. The new graph should look like the one below, except with two points/CI bars for each label on the Y axis.

The following example is from the lme4 package, and it produces a plot with confidence intervals using ggplot below (all can be replicated except the last two lines of borken code). My data is only different in that it includes about 15 intercepts instead of 6 below (which is why I am using scale_shape_manual).

The last two lines of code is my attempt at adding points/confidence intervals. I'm going to put a 50 bounty on this. Please let me know if I am being unclear. Thanks!

library("lme4")
data(package = "lme4")

# Dyestuff 
# a balanced one-way classiï¬cation of Yield 
# from samples produced from six Batches

summary(Dyestuff)             

# Batch is an example of a random effect
# Fit 1-way random effects linear model
fit1 <- lmer(Yield ~ 1 + (1|Batch), Dyestuff) 
summary(fit1)
coef(fit1) #intercept for each level in Batch 


randoms<-ranef(fit1, postVar = TRUE)
qq <- attr(ranef(fit1, postVar = TRUE)[[1]], "postVar")

rand.interc<-randoms$Batch

#THESE ARE THE ADDITIONAL POINTS TO BE ADDED TO THE PLOT
Inter <- c(-25,-45,20,30,23,67)
SE2 <- c(20,20,20,20,20,20)

df<-data.frame(Intercepts=randoms$Batch[,1],
           sd.interc=2*sqrt(qq[,,1:length(qq)]), Intercepts2=Inter, sd.iterc2=SE2,
           lev.names=rownames(rand.interc))

df$lev.names<-factor(df$lev.names,levels=df$lev.names[order(df$Intercepts)])

library(ggplot2)
p <- ggplot(df,aes(lev.names,Intercepts,shape=lev.names))

#Added horizontal line at y=0
#Includes first set of points/confidence intervals.  This works without error
p <- p + geom_hline(yintercept=0) +geom_errorbar(aes(ymin=Intercepts-sd.interc, ymax=Intercepts+sd.interc), width=0,color="black") + geom_point(aes(size=2)) 

#Removed legends and with scale_shape_manual point shapes set to 1 and 16
p <- p + guides(size=FALSE,shape=FALSE) + scale_shape_manual(values=c(16,16,16,16,16,16))

#Changed appearance of plot (black and white theme) and x and y axis labels
p <- p + theme_bw() + xlab("Levels") + ylab("")

#Final adjustments of plot
p <- p + theme(axis.text.x=element_text(size=rel(1.2)),
           axis.title.x=element_text(size=rel(1.3)),
           axis.text.y=element_text(size=rel(1.2)),
           panel.grid.minor=element_blank(),
           panel.grid.major.x=element_blank())

#To put levels on y axis you just need to use coord_flip()
p <- p+ coord_flip()
print(p)

#####
# code for adding more plots, NOT working yet
p <- p +geom_errorbar(aes(ymin=Intercepts2-sd.interc2, ymax=Intercepts2+sd.interc2), 
                    width=0,color="gray40", lty=1, size=1) 

p <- p + geom_point(aes(Intercepts2, lev.names),size=0,pch=7)
1
I think you're wrong, actually, and geom_step is not what you want at all. Can you describe the actual intended result in words? i.e. describe what should be plotted?joran
Sorry if I wasn't clear. I updated at the beginning of my post a description of what I am looking for. And I may very well be wrong on using geom_step, and that could be part of my problem. Please let me know if I am still being unclear. Thanks.Captain Murphy
Well, to directly add more points exactly like the others, you should just be using geom_point. But they're going to overlap. See here instead.joran
ahhh, thank you! I do want them to overlap, so that is good. Let me go through that link, and see if it works. CheersCaptain Murphy
Ok, if you don't care if they overlap, just go through the same process with geom_errorbar and geom_point that you did for the first set, and you should be fine.joran

1 Answers

3
votes

First, in your data frame df and geom_errorbar() there are two different variables sd.iterc2 and sd.interc2. Changed also in df to sd.interc2.

For the last line of geom_point() you get the error because your x and y values are in wrong order. As your are using coord_flip() then x and y values should be placed in the same order as in original plot before coord_flip(), that is, lev.names as x, and Intercepts2 as y. Changed also size= to 5 for better illustration.

+ geom_point(aes(lev.names,Intercepts2),size=5,pch=7)

enter image description here

Update - adding legend

To add legend for the points of intercept types, one option is to reshape your data to long format and add new column with intercept types. Other option with your existing data is, first, remove shape=lev.names from ggplot() call. Then in both geom_point() calls add shape="somename" inside aes(). Then with scale_shape_manual() set shape values you need.

ggplot(df,aes(lev.names,Intercepts))+
  geom_hline(yintercept=0) + 
  geom_errorbar(aes(ymin=Intercepts-sd.interc, ymax=Intercepts+sd.interc), width=0,color="black")+
  geom_point(aes(shape="Intercepts"),size=5)+
  theme_bw() + xlab("Levels") + ylab("")+
  theme(axis.text.x=element_text(size=rel(1.2)),
        axis.title.x=element_text(size=rel(1.3)),
        axis.text.y=element_text(size=rel(1.2)),
        panel.grid.minor=element_blank(),
        panel.grid.major.x=element_blank())+
  coord_flip()+
  geom_errorbar(aes(ymin=Intercepts2-sd.interc2, ymax=Intercepts2+sd.interc2), 
                        width=0,color="gray40", lty=1, size=1) + 
  geom_point(aes(lev.names,Intercepts2,shape="Intercepts2"),size=5)+
  scale_shape_manual(values=c(16,7))

enter image description here