Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make dodge in geom_bar agree with dodge in geom_errorbar, geom_point

I have a dataset where measurements are made for different groups at different days.

I want to have side by side bars representing the measurements at the different days for the different groups with the groups of bars spaced according to day of measurement with errorbars overlaid to them.

I'm having trouble with making the dodging in geom_bar agree with the dodge on geom_errorbar.

Here is a simple piece of code:

days          = data.frame(day=c(0,1,8,15));
groups        = data.frame(group=c("A","B","C","D", "E"), means=seq(0,1,length=5));


my_data       = merge(days, groups);


my_data$mid   = exp(my_data$means+rnorm(nrow(my_data), sd=0.25));
my_data$sigma = 0.1;


png(file="bar_and_errors_example.png", height=900, width=1200);
plot(ggplot(my_data, aes(x=day, weight=mid, ymin=mid-sigma, ymax=mid+sigma, fill=group)) +
     geom_bar      (position=position_dodge(width=0.5))                                   +
     geom_errorbar (position=position_dodge(width=0.5), colour="black")                   +
     geom_point    (position=position_dodge(width=0.5), aes(y=mid, colour=group)));
dev.off();

In the plot, the errorsegments appears with a fixed offset from its bar (sorry, no plots allowed for newbies even if ggplot2 is the subject).

When binwidth is adjusted in geom_bar, the offset is not fixed and changes from day to day.

Notice, that geom_errorbar and geom_point dodge in tandem. How do I get geom_bar to agree with the other two?

Any help appreciated.

like image 464
user1771185 Avatar asked Oct 24 '12 13:10

user1771185


Video Answer


4 Answers

The alignment problems are due, in part, to your bars not representing the data you intend. The following lines up correctly:

ggplot(my_data, aes(x=day, weight=mid, ymin=mid-sigma, ymax=mid+sigma, fill=group)) +
     geom_bar      (position=position_dodge(), aes(y=mid), stat="identity") +
     geom_errorbar (position=position_dodge(width=0.9), colour="black") +
     geom_point    (position=position_dodge(width=0.9), aes(y=mid, colour=group))

enter image description here

like image 95
Brian Diggs Avatar answered Oct 06 '22 16:10

Brian Diggs


This is an old question, but since i ran into the problem today, i want to add the following:

In

 geom_bar(position = position_dodge(width=0.9), stat = "identity") + 
   geom_errorbar( position = position_dodge(width=0.9), colour="black") 

the width-argument within position_dodge controls the dodging width of the things to dodge from each other. However, this produces whiskers as wide as the bars, which is possibly undesired. An additional width-argument outside the position_dodge controls the width of the whiskers (and bars):

 geom_bar(position = position_dodge(width=0.9), stat = "identity", width=0.7) + 
   geom_errorbar( position = position_dodge(width=0.9), colour="black", width=0.3) 
like image 24
nouse Avatar answered Oct 06 '22 15:10

nouse


The first change I reformatted the code according to the advanced R style guide.

days <- data.frame(day=c(0,1,8,15))

groups <- data.frame(
    group=c("A","B","C","D", "E"), 
    means=seq(0,1,length=5)
    )

my_data <- merge(days, groups)

my_data$mid <- exp(my_data$means+rnorm(nrow(my_data), sd=0.25))
my_data$sigma <- 0.1

Now when we look at the data we see that day is a factor and everything else is the same.

str(my_data)

To remove blank space from the plot I converted the day column to factors. CHECK that the levels are in the proper order before proceeding.

my_data$day <- as.factor(my_data$day) 
levels(my_data$day)

The next change I made was defining y in your aes arguments. As I'm sure you are aware, this lets ggplot know where to look for y values. Then I changed the position argument to "dodge" and added the stat="identity" argument. The "identity" argument tells ggplot to plot y at x. geom_errorbar inherits the dodge position from geom_bar so you can leave it unspecified, but geom_point does not so you must specify that value. The default dodge is position_dodge(.9).

ggplot(data = my_data, 
 aes(x=day,
     y= mid, 
     ymin=mid-sigma, 
     ymax=mid+sigma,       
     fill=group)) +
   geom_bar(position="dodge", stat = "identity") + 
   geom_errorbar( position = position_dodge(), colour="black") +
   geom_point(position=position_dodge(.9), aes(y=mid, colour=group))

enter image description here

like image 4
Collin Avatar answered Oct 06 '22 16:10

Collin


sometimes you put aes(x=tasks,y=val,fill=group) in geom_bar rather than ggplot. This causes the problem since ggplot looks forward x and you specify it by the location of each group.

like image 4
Javid Dadashkarimi Avatar answered Oct 06 '22 15:10

Javid Dadashkarimi