[R] ggplot2: how to combine position=stack and position=dodge in a single graph?

Sebastian Krollmann sebastian.krollmann at gmx.net
Sun Oct 26 00:09:08 CEST 2008


Hi Hadley,

I tried to replicate dodging in combination with stacking by facetting 
as you suggested.
In principle this works, but identifying the bars for different years is 
very difficult, since the all bar colors are the same (see my code below).
Is there a way of having the bars within each facet filled with 
different colors, i.e. different color for each year?
Together with a legend this would make the plot much more easy to 
understand.

Nevertheless I am curious how the solution for the first approach will 
look like. What about selection different colors in this case? How could 
this be done?

Thanks a lot for all your help,

-- Elena

The code:

# compare different months of different years with facetted plots
gg = ggplot(nc_dat,
             aes(x=CommitYear,
                 y=Price,
                 fill=factor(newCust),
                 width=0.85)
             )
#gg = gg + geom_bar(stat="identity")
gg = gg + geom_bar(stat="identity") +  facet_grid(. ~ CommitMonth)
gg


Elena wrote:

Hi Hadley,

thanks a lot for your quick answer.
> You should be able to replicate any dodging layout with facetting
You mean instead of facetting by years, facetting by months? I will try
this an see how the plot looks.

> shift the second layer across a bit
> with aes(x=as.numeric(CommitMont) + 0.5)).
I tried this, but it didn't work with my data. I think due to the fact
that I am quite new to R.

> please send me a reproducible example.
It took me a bit to create some reproducible example data that shows my
problem. Please see the example script below.

Wouldn't it be more intuitive to have some parameters for layers like
stacking=c(s1, s2, ...), dodging=c(d1, d2), ..., or is the combination
of both so rarely used?

Thanks a lot for your help to get it work with the below script.

-- Elena


Here is my script:

# create artificial timeseries data
library("its")
n = 12*2*20 # number of values = 12 * nyears * npermonth
tser = newIts(start="2006-01-01",end="2007-12-31", period="month",
find="last", extract=TRUE, weekday=FALSE)
t = strptime(dates(tser), format="%Y-%m-%d")
CommitMonth = strftime(t, "%m")
CommitYear = strftime(t, "%Y")
n = 24*20 # number of values
Price = rnorm(1000, mean = 1000, sd = 500)[1:n]
newCust = as.logical(round(runif(n, min=0, max=1)))
c_dat = data.frame(cbind(CommitYear, CommitMonth, newCust), Price)
summary(c_dat)
str(c_dat)
# use reshape for flexibility
library("reshape")
c_datM = melt(c_dat,
                id = c("CommitYear", "CommitMonth", "newCust"),
                measured = c("Price"),
                na.rm = TRUE)
nc_dat = cast(c_datM, CommitMonth + CommitYear + newCust ~ variable, sum)
summary(nc_dat)
# separate data for different years
nc_dat_06 = subset(nc_dat, CommitYear == 2006)
nc_dat_07 = subset(nc_dat, CommitYear == 2007)

# try to combine dodging and stacking
library("ggplot2")
ggplot() +
layer(data = nc_dat_07,
       mapping = aes(x=CommitMonth,
                 y=Price,
                 fill = factor(newCust),
                 width=0.4),
       geom="bar",
       colour="red",
       stat="identity"
       ) +
layer(data = nc_dat_06,
       mapping = aes(x=factor(as.numeric(CommitMonth)+.5),
                 y=Price,
                 fill=factor(newCust),
                 width=0.4
                 ),
       geom="bar",
       colour="black",
       stat="identity"
       )


hadley wickham wrote:
> Hi Elena,
> 
> You should be able to replicate any dodging layout with facetting, but
> you should be to shift the second layer across a bit with
> aes(x=as.numeric(CommitMont) + 0.5)).  If that doesn't work, please
> send me a reproducible example.
> 
> Hadley
> 
> On Tue, Oct 21, 2008 at 3:59 PM, Elena Schulz <elena.schulz at gmx.net> wrote:
>> Hi Hadley,
>>
>> my problem is that I want to compare data for different years month by
>> month. Each bar for a month is devided into two or more sections (->
>> stacking) By having all data of the same month right next to each other (->
>> dodging) comparision is much more easy than using faceting which does not
>> show subtle differences within the same month of different years since all
>> years get separated.
>>
>> My approach to allow combining of stacking and dodging in a single
>> graphic would be the following:
>>
>> # compare different years in one plot
>> # combine position_stack with position_dodge
>> ggplot() +
>> layer(data = nc_dat_06,
>>      mapping = aes(x=CommitMonth,
>>                y=Price,
>>                fill = factor(newCust),
>>                width=0.4),
>>      geom="bar",
>>      colour="red",
>>      stat="identity"
>>      ) +
>> layer(data = nc_dat_07,
>>      mapping = aes(x=CommitMonth,
>>                y=Price,
>>                fill=factor(newCust),
>>                width=0.4
>>                ),
>>      geom="bar",
>>      colour="black",
>>      stat="identity"
>>      )
>>
>> This works except that the second layer (data = nc_dat_07) is plotted right
>> on top of the first one (data = nc_dat_06). If I could find a way to shift
>> the whole second layer (data = nc_dat_07) a bit parallel to the x axis, I'm
>> done. Is there an easy way for this? Adding an x-offset value to a layer?
>>
>> Thanks for any help on this,
>>
>> -- Elena
>>
>>
>> hadley wickham wrote:
>>> Hi Elena,
>>>
>>> Currently, there's no way to combine stacking and dodging in a single
>>> graphic.  However, you can often use faceting to get a similar effect
>>> to dodging.  Could you explain your problem in a little more detail?
>>>
>>> Thanks,
>>>
>>> Hadley
>>>
>>> On Sat, Oct 4, 2008 at 4:22 PM, Elena Schulz <elena.schulz at gmx.net> wrote:
>>>> Hi ggplot experts,
>>>>
>>>> I need to plot two time series of stacked data: a barchart with bars for
>>>> each month. To compare the data of two years I need to combine both time
>>>> series with in a single graph via position=doge.
>>>> How should I do that?
>>>>
>>>> I tried the following scenario:
>>>> I added two layers with the time series of the stacked data for both
>>>> years.
>>>> That worked well exept the bars are obscuring each other. How can  I
>>>> shift
>>>> one of the layers to get them displayed next to each other.
>>>>
>>>> Is there an other easier way to achieve this?
>>>>
>>>> Thanks a lot for any help on this.
>>>>
>>>> -- Elena
>>>>
>>>> ______________________________________________
>>>> R-help at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>>> PLEASE do read the posting guide
>>>> http://www.R-project.org/posting-guide.html
>>>> and provide commented, minimal, self-contained, reproducible code.
>>>>
>>>
>>>
>>
> 
> 
>



More information about the R-help mailing list