fede_luppi
fede_luppi

Reputation: 1171

geom_lines not linking what they should with error bars plot in ggplot

I have the following dataset ready to plot an error bars and lines graph

> growth
   treatment       class variable  N       value          sd          se          ci
1   elevated    Dominant RBAI2012 18 0.014127713 0.009739951 0.002295728 0.004843564
2   elevated    Dominant RBAI2013 18 0.021869978 0.013578741 0.003200540 0.006752549
3   elevated  Codominant RBAI2012 40 0.011564725 0.013718591 0.002169100 0.004387418
4   elevated  Codominant RBAI2013 41 0.011471512 0.011091167 0.001732149 0.003500804
5   elevated Subordinate RBAI2012 24 0.004419784 0.009286883 0.001895677 0.003921507
6   elevated Subordinate RBAI2013 24 0.004397105 0.008704831 0.001776866 0.003675728
7    ambient    Dominant RBAI2012 13 0.025836265 0.011880315 0.003295007 0.007179203
8    ambient    Dominant RBAI2013 13 0.025992636 0.015162901 0.004205432 0.009162850
9    ambient  Codominant RBAI2012 26 0.018067329 0.011830940 0.002320238 0.004778620
10   ambient  Codominant RBAI2013 26 0.015595275 0.012467140 0.002445007 0.005035587
11   ambient Subordinate RBAI2012 33 0.006073904 0.008287442 0.001442658 0.002938599
12   ambient Subordinate RBAI2013 35 0.003239033 0.006846507 0.001157271 0.002351857

I've tried the following code, resulting this plot:

p <- ggplot(growth,aes(class,value,colour=treatment,group=variable))
pd<-position_dodge(.9)
# se= standard error; ci=confidence interval
p + geom_errorbar(aes(ymin=value-se,ymax=value+se),width=.1,position=pd,colour="black") + geom_point(position=pd,size=4) + geom_line(position=pd) + 
  theme_bw() + theme(legend.position=c(1,1),legend.justification=c(1,1))

enter image description here

The lines should link the points of their same color within each x-axis category, but clearly they don't. Please, could you help me draw the lines properly (e.g blue with blue and red with red within "Dominant" class, different lines for "codominant" class. Also, do you know how to include in the x-labels the variables I am grouping with (i.e. "RBAI2012","RBAI2013"? Many thanks

Upvotes: 1

Views: 2805

Answers (4)

Henrik
Henrik

Reputation: 67778

To distinguish also between different of levels of 'variable' you may introduce a fourth aesstetic: shape. First define a new grouping variable, a combination of 'treatment' and 'variable', which has four levels. Map group, colours and shape to this variable. Then use scale_colour_manual and scale_shape_manual to set two levels of colours, which corresponds to the two levels of 'treatment'. Similarly, define two 'variable' shapes.

growth$grp <- paste0(growth$treatment, growth$variable)

ggplot(data = growth, aes(x = class, y = value, group = grp,
                      colour = grp, shape = grp)) +
  geom_point(size = 4, position = pd) +
  geom_line(position = pd) +
  geom_errorbar(aes(ymin = value - se, ymax = value + se), colour = "black",
                position = pd, width = 0.1) +
  scale_colour_manual(name = "Treatment:Variable",
                      values = c("red", "red","blue", "blue")) +
  scale_shape_manual(name = "Treatment:Variable",
                     values = c(19, 17, 19, 17))
  theme_bw() +
  theme(legend.position = c(1,1), legend.justification = c(1,1))

enter image description here

Upvotes: 1

Troy
Troy

Reputation: 8691

It is possible to do this, but you need to hack it since you're essentially plotting a geom_line() on different groupings (variable + treatment) than with the geom_point() and geom_errorbar() calls.

You need to use ggplot_build() to get back the rendered data and draw a geom_line(), based on the existing points data, grouped by colour:

p <- ggplot(growth)          # move the aes() into the individual charts
pd<-position_dodge(.9)       # leave dodge as is
se<-0.01                     # faked this

p <- p + 
  geom_point(aes(x=factor(class),y=value,colour=treatment,group=variable),position=pd,size=4) +
  theme_bw() + theme(legend.position=c(1,1),legend.justification=c(1,1)) +
  geom_errorbar(aes(x=factor(class),ymin=value-se,ymax=value+se,colour=treatment,group=variable),position=pd,width=.1,colour="black")

b<-ggplot_build(p)$data[[1]]  # get the ggpolt rendered data for this panel

p + geom_line(data=b,aes(x,y,group=colour), color=b$colour) # plot the lines

enter image description here

Upvotes: 0

mbask
mbask

Reputation: 2481

You have too many grouping variables (variable and treatment) and including them in a single plot may be a bit confusing. You might want to use faceting, like this:

p <- ggplot(growth,aes(class,value,colour=treatment,group=treatment))
pd<-position_dodge(.9)
p + 
  geom_errorbar(aes(ymin=value-se,ymax=value+se),width=.1,position=pd,colour="black") +
  geom_point(position=pd,size=4) + geom_line(position=pd) + 
  theme_bw() + theme(legend.position=c(1,1),legend.justification=c(1,1)) +
  facet_grid(variable~treatment)

enter image description here

Upvotes: 0

MC808
MC808

Reputation: 178

One option is using a facet plot like so:

p <- ggplot(growth, aes(x = class, y = value, group = treatment, color = treatment))
p + geom_point(size = 4) + facet_grid(. ~ variable) + geom_errorbar(aes(ymin=value-se,ymax=value+se),width=.1,colour="black") + geom_line()

If you want it on one graph, another option is defining a new variable that combines treatment and variable:

growth$treatment_variable <- paste(growth$treatment, growth$variable)
p <- ggplot(growth, aes(x = class, y = value, group = treatment_variable, colour = treatment_variable))
pd<-position_dodge(.2)
p + geom_point(size = 4, position=pd) + geom_errorbar(aes(ymin=value-se, ymax=value+se), width=.1, position=pd, colour="black") + geom_line(position=pd)

Upvotes: 0

Related Questions