2

Using ggplot2, how can we selectively choose the direction of error bars? I have a 4-line plot whose error bars overlap and I would like to manually choose which ones should appear only positive or negative SE or SDs.

Here is what I have so far. I first plot it without error bars:

require("ggplot2")
ggplot(data.long, 
       aes(y = values, x = within_2, group = interaction(Between, within_1), linetype = within_1)) + 
  stat_summary(geom="line", fun.y="mean") +
  stat_summary(geom="point", fun.y="mean", aes(shape = Between)) + 
  scale_shape_manual(values = c(0, 17)) + 
  labs(x = "xlab", y = "% change")

enter image description here

Then I summarise data to obtain SE and SD:

require("Hmisc")
data_summary <- summarySE(data.long, measurevar="values", groupvars=c("within_1","within_2", "Between"))  

Plot with error bars:

  ggplot(data_summary, 
         aes(y = values, x = within_2, group = interaction(Between, within_1), linetype = within_1)) + 
    stat_summary(geom="line", fun.y="mean") +
    stat_summary(geom="point", fun.y="mean", aes(shape = Between)) + 
    scale_shape_manual(values = c(0, 17)) + 
    labs(x = "xlab", y = "% change") +
    geom_errorbar(aes(ymin = values-se, ymax = values+se),
                  width=.2)

enter image description here

How could plot only upper or lower error bars on different lines to improve plot visuals? Here there's a solution that seems to be on the way, but I am unable to reproduce it in my 4-line plot.

Here is the data:

data.long <- structure(list(Between = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("CT", 
"TT"), class = "factor"), within_1 = structure(c(2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = c("N", "H"), class = "factor"), within_2 = c("1", 
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
"1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2", "2", 
"2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "3", "3", 
"3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", 
"3", "3", "3", "3", "4", "4", "4", "4", "4", "4", "4", "4", "4", 
"4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "5", "5", "5", 
"5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", 
"5", "5", "5", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", 
"6", "6", "6", "6", "6", "6", "6", "6", "6", "1", "1", "1", "1", 
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
"1", "1", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", 
"2", "2", "2", "2", "2", "2", "2", "2", "3", "3", "3", "3", "3", 
"3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", 
"3", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", 
"4", "4", "4", "4", "4", "4", "4", "5", "5", "5", "5", "5", "5", 
"5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", 
"6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", 
"6", "6", "6", "6", "6", "6"), values = c(-1.4210854715202e-14, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1.4210854715202e-14, 0, 0, -1.4210854715202e-14, 
0, 0, 0, 1.4210854715202e-14, 0, -10.6057583104295, 3.82366147137421, 
4.70566944216206, 0.187724131379127, -2.03535330384851, 2.2524979765733, 
-2.9727148766444, 2.6083885402083, -4.61360697651398, -6.66382102505303, 
-1.89755148846209, 1.93353333867543, -3.11983762126631, -1.4345951465109, 
1.24952019949389, -3.11650324404344, -6.24550613366193, 1.00162236282669, 
3.03857695742765, -13.5070034150553, 3.77730864186645, 2.93181434857114, 
1.24485299776214, -8.79147436639039, 1.12367346753739, -4.94643186841199, 
-1.27354690713364, -9.08208771404033, -2.29587905024601, -0.886178182878069, 
4.50975449028302, -1.15072253151024, 0.418168345464125, 1.73306387514543, 
-3.40039886806825, -0.619776296430885, -2.99138061415866, 0.00261916388753036, 
-13.1610198532011, 2.36046192675914, 3.38443628501334, -1.67355568218787, 
-12.1136956835012, 1.89806525735736, -5.61536574685965, -4.07184931448117, 
-10.0281915596217, -8.25975424526955, -2.23420107114791, 6.16533079297051, 
-3.48741869496304, -5.34701895515406, 0.442597528682782, -4.8531422721731, 
-6.71971984650138, 0.55633231142032, 4.90437903753043, -18.1078379702318, 
1.62222015009712, 2.13720100979083, -1.17309255429642, -12.78396026415, 
0.729862841243275, -8.85206491114279, -8.31362171333841, -14.7101795669535, 
-1.79048494987613, -1.49496076749276, 3.41185281739396, -0.838416866619227, 
-2.9855687917721, 0.981470329055682, -0.468618335177922, 1.9761737856014, 
-3.11961635987447, 0.0122101591331756, -18.3764354546495, -0.839562634101327, 
-0.909215798953383, -3.04660579184322, -15.527856021636, -0.211986565635385, 
-10.2270437446076, -8.11032597620989, -17.0205715878628, -6.69427611524303, 
-3.74938133414415, 3.32631128248181, -8.32452015678412, -7.4699177381065, 
2.44417772472276, -6.43767201678928, -6.74659357477346, 0.344765610464776, 
3.07591251998821, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, -1.68055460693036, 0.561182122946207, 6.04376427020478, 
0.52606038309024, -1.92041213359749, 2.84769535274846, -4.09729336005844, 
-1.38630866031168, -4.40117348808879, -4.80696362592231, 0.524936720222485, 
-0.225035184695145, -0.720841177736872, 0.378127221604487, -2.17560352140093, 
-4.09583471719559, -5.77744921646007, 0.610060458577692, 4.7775865643377, 
-5.0208861691041, -0.881834167779218, 2.26361403828709, 1.81046574431237, 
-5.14112669366628, 3.73205231339362, -5.08511489358583, -3.82150725680953, 
-9.70438917132918, 0.33075871579895, -0.867931790168782, 1.19904914200561, 
-1.29825049887336, -0.113067560520705, 0.400223130726687, -2.18141887602395, 
-1.79457229366905, -2.16359725691149, 4.00029213506218, -9.21970490935017, 
-1.61596728535645, 2.18558304627001, 1.29045467896481, -8.54718013614946, 
2.05156900518132, -7.72721674043164, -9.38186074302632, -10.2589110749438, 
-5.64651239627536, -1.51893967360546, 2.6898530761015, -3.21933963350499, 
-0.553289096780574, -0.718499298125963, -7.41824549357261, -5.36249002000503, 
-2.33002523562874, 8.12201643395576, -11.4677701393646, -6.97071057624974, 
-0.551803400141694, 2.85443044484461, -10.4245256849277, 0.514338249427183, 
-9.02993382055641, -10.5768230419275, -14.1344173532463, 0.11489370036935, 
0.00285183138591094, 4.31327888241417, -1.27799113923298, -0.914744528454023, 
0.127682993945172, -4.87142828001647, -1.01903492042325, -0.83963875573221, 
0.896505058481708, -14.8096831429394, -5.90071739612186, 1.63305204156767, 
3.08190814542317, -14.00192066133, 0.641853802476064, -11.3190314697168, 
-13.2537662623402, -18.806303898898, -7.0410921988907, -2.65318926213971, 
7.46825055830635, -5.51894689174026, -1.20587792674647, 0.974813882949832, 
-5.8574589151346, -5.92200551366662, -2.7927135341117, 2.24223786198247
)), row.names = c(NA, -228L), .Names = c("Between", "within_1", 
"within_2", "values"), class = "data.frame")
neilfws
  • 32,751
  • 5
  • 50
  • 63
AJMA
  • 1,134
  • 2
  • 13
  • 28
  • 2
    Looks to me that you will have to do it manually. Summarize the mean and the SD in a data.frame and then calculate ymax and ymin with them. Then change the ymax column to the value of the mean to remove the upper errorbar, or viceversa for those where you want to plot only the lower errorbar. Then feed geom_errorbar with these columns. – Osdorp May 26 '17 at 07:13

1 Answers1

2

maybe this can help you:

data_summary <- Rmisc::summarySE(data.long, measurevar="values",
                                 groupvars=c("within_1","within_2", "Between"))


#Based on the solution you found. 
data_summary$min <- data_summary$values - ((data_summary$Between=='CT' & data_summary$within_1=='H')|
                                            (data_summary$Between=='TT'& data_summary$within_1=='H'))*
                                            data_summary$se

data_summary$max <- data_summary$values + ((data_summary$Between=='CT' & data_summary$within_1=='N')|
                                            (data_summary$Between=='TT'& data_summary$within_1=='N'))*
                                            data_summary$se

ggplot(data_summary, 
       aes(y = values, x = within_2, group = interaction(Between, within_1), linetype = within_1)) + 
  stat_summary(geom="line", fun.y="mean") +
  stat_summary(geom="point", fun.y="mean", aes(shape = Between)) + 
  scale_shape_manual(values = c(0, 17)) + 
  labs(x = "xlab", y = "% change",title="New columns:min and max") +
  geom_errorbar(aes(ymin = min, ymax = max),
                width=.2)

enter image description here

You can still get the same result using two geom_errorbar() subsetting for each geom_bar the appropiate data:

ggplot(data_summary, 
   aes(y = values, x = within_2, group = interaction(Between, within_1), linetype = within_1)) + 
 stat_summary(geom="line", fun.y="mean") +
 stat_summary(geom="point", fun.y="mean", aes(shape = Between)) + 
 scale_shape_manual(values = c(0, 17)) + 
 labs(x = "xlab", y = "% change",title="2 geom_errorbar") +
 geom_errorbar(data=with(data_summary,data_summary[which(Between=='CT'& within_1=='H' |
                                                          Between=='TT'& within_1=='H'),]),
            aes(ymin = values-se, ymax = values),
            width=.2)+
 geom_errorbar(data=with(data_summary,data_summary[which(Between=='CT'& within_1=='N' |
                                                          Between=='TT'& within_1=='N'),])
            ,aes(ymin = values, ymax = values+se),
            width=.2)

enter image description here

One-side caps

A possible workaround could be to put width=0 in the geom_errorbar options and generate the caps using geom_segment.

ggplot(data_summary, 
   aes(y = values, x = within_2, group = interaction(Between, within_1), linetype = within_1)) + 

 stat_summary(geom="line", fun.y="mean") +
 stat_summary(geom="point", fun.y="mean", aes(shape = Between)) + 
 scale_shape_manual(values = c(0, 17)) + 
 labs(x = "xlab", y = "% change",title="2 geom_errorbar - One-side caps") +

 #errorbar without caps 

 geom_errorbar(data=with(data_summary,data_summary[which(Between=='CT'& within_1=='H' |
                                                          Between=='TT'& within_1=='H'),]),
            aes(ymin = values-se, ymax = values),width=0)+
 geom_errorbar(data=with(data_summary,data_summary[which(Between=='CT'& within_1=='N' |
                                                          Between=='TT'& within_1=='N'),]),
            aes(ymin = values, ymax = values+se),width=0)+

 #geom_segment for caps 

 geom_segment(data=with(data_summary,data_summary[which(Between=='CT'& within_1=='H' |
                                                           Between=='TT'& within_1=='H'),]),
               aes(y=values-se,yend=values-se,x= as.numeric(within_2)-0.1,xend= as.numeric(within_2)+0.1))+

  geom_segment(data=with(data_summary,data_summary[which(Between=='CT'& within_1=='N' |
                                                           Between=='TT'& within_1=='N'),]),
               aes(y=values+se,yend=values+se,x= as.numeric(within_2)-0.1,xend= as.numeric(within_2)+0.1))

enter image description here

Hope this helps!

storm surge
  • 841
  • 8
  • 9
  • Thanks that does the job. Any idea of how caps from error bars can be removed from one side? – AJMA May 26 '17 at 14:29
  • Setting geom_errorbar(width = 0) works, but caps are removed from both edges. How could it be done only on one edge? – AJMA May 26 '17 at 14:57
  • 1
    @AJMA, I don't know if it is possible, however I have edited my answer with a possible workaround that uses geom_segment. – storm surge May 27 '17 at 10:50
  • I was wondering if the following could be easily done on the example above: change the direction of error bars selectively for one of the within_2 variables, leaving the others as they are? Thank you – AJMA Jul 21 '17 at 10:08