Binned fill aesthetic in geom_area

135 views
Skip to first unread message

Paul

unread,
Nov 29, 2012, 5:39:03 AM11/29/12
to ggp...@googlegroups.com
Dear all,

I'd like to produce a frequency power spectrum with EEG data. This works fine but coloring the area below the line by frequency bands does not work so well. Here is what I'd like to achieve:


Here's a data snipped with the data which underlies the above plot:

load(url("http://dl.dropbox.com/u/6281903/snippet.Rda"))

This is what the data looks like:

> head(dd)
         Hz power  band
1 0.9765625 0.123 delta
2 1.9531250 9.511 delta
3 2.9296875 0.777 delta
4 3.9062500 3.702 theta
5 4.8828125 5.138 theta
6 5.8593750 2.636 theta

The following code reduces the plot nicely but without coloring:

ggplot(data=dd, aes(x=Hz, y=power)) +
  geom_area() +
  theme_bw() + xlim(0, 32) + ylab(expression(paste(µV^2/Hz)))


Adding a fill aesthetic produces gaps between the frequency bands where the data was interpolated before:

ggplot(data=dd, aes(x=Hz, y=power)) +
  geom_area(aes(fill=band)) +
  scale_fill_brewer(palette = "Set1", na.value = NA, guide = "none") +
  theme_bw() + xlim(0, 32) + ylab(expression(paste(µV^2/Hz)))

Is there some way how I can fix this plot? I'm grateful for any suggestions you might have.

Paul

unread,
Nov 29, 2012, 9:32:31 AM11/29/12
to ggp...@googlegroups.com
I found two workarounds but only one is really an option. I could close the gaps by interpolating the area between the Hz values but the plot only looks continuous when the interpolation is really dense and that results in unreasonably huge data sets. The other option is to draw rectangles and cover the area above the line with whitespace. That is what I'm doing now, the code looks like this:

ggplot(data=dd, aes(x=Hz, y=power)) +
  geom_rect(xmin=subdelta[1], xmax=subdelta[2], ymin = 0, ymax = max(dd$power), fill = "grey70") +
  geom_rect(xmin=delta[1], xmax=delta[2], ymin = 0, ymax = max(dd$power), fill = "orange") +
  geom_rect(xmin=theta[1], xmax=theta[2], ymin = 0, ymax = max(dd$power), fill = "yellow") +
  geom_rect(xmin=alpha[1], xmax=alpha[2], ymin = 0, ymax = max(dd$power), fill = "forestgreen") +
  geom_rect(xmin=beta[1], xmax=beta[2] - 1, ymin = 0, ymax = max(dd$power), fill = "blue") +  
  geom_vline(x=0) + geom_hline(y=0, width = 28) +
  geom_ribbon(aes(ymin=power), ymax=max(dd$power), fill = "white") +
  xlim(0, beta[2]) + ylim(0, max(dd$power)) +
  scale_x_continuous(expand=c(0,0.5)) +
  scale_y_continuous(expand=c(0,0.05))+
  theme_bw() +
  theme(panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        panel.border=element_blank(),
        axis.ticks.y = element_blank()) +
  ylab(expression(paste(µV^2/Hz)))

The result is this:

 Still, I would rather go for the simpler solution and plot this with geom_area.
Reply all
Reply to author
Forward
0 new messages