Plot band of uncertainty

227 views
Skip to first unread message

Johannes Radinger

unread,
May 7, 2012, 10:00:35 AM5/7/12
to ggp...@googlegroups.com
Hi,

I would like to plot a band of uncertainty based on data
that are produced externally. The data comprise of cumulative
values for the mean (called fit) and a lower and upper bound (lwr, upr).
The problem is that the vectors of lwr, upr and fit are of different
length and they are molten in a dataframe.

A small sample dataset how my data look like:

var <- rep(c("lwr","upr","fit"),c(50,80,45))
y <- c(sort(runif(50,1,20)),sort(runif(80,50,70)),sort(runif(45,20,50)))
x <- c(sort(runif(50,1,100)),sort(runif(80,1,100)),sort(runif(45,1,100)))
df <- data.frame(var,x,y)

ggplot(df,aes(x=x,y=y,colour=var))+geom_line()

It is no problem to plot the three lines (see output of the ggplot command).
But instead of plotting the lines for upr and lwr, I'd like to plot a band/area like the geom_ribbon. I think in this case geom_ribbon wont work...Is there any possiblity to make such a plot? If yes, what is the corresponding ggplot function and how do I need to reshape my data?



best regards,

Johannes
--
NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone!
Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a

Joran

unread,
May 7, 2012, 11:04:02 AM5/7/12
to ggp...@googlegroups.com
One option would be to simply interpolate the lower and upper values to create a new data frame to pass to geom_ribbon:

r <- range(df$x[df$var != 'fit'])
xout <- seq(r[1],r[2],length.out = 200)

lower <- with(df,approx(x[var == 'lwr'],y = y[var == 'lwr'],xout = xout,rule = 2))$y
upper <- with(df,approx(x[var == 'upr'],y = y[var == 'upr'],xout = xout,rule = 2))$y

df1 <- data.frame(x = xout,lower = lower,upper = upper)

ggplot(df) + 
geom_ribbon(data = df1,aes(x = xout,ymin = lower,ymax = upper),alpha = 0.5) +
geom_line(aes(x=x,y=y,group = var))

Johannes Radinger

unread,
May 7, 2012, 4:02:09 PM5/7/12
to Joran, ggp...@googlegroups.com
Hi,

interpolating sounds like a good option for my case. Thank you Joran!
Anyway there is just one issue i've to solve: My acutal dataframe has
also 3 additional columns I need for facetting. Thus I
need to use the approx-function on the whole dataframe (probably using
ddply etc). I've to think about that...or maybe someone is faster with
a solution...

best regards

/johannes
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

Johannes Radinger

unread,
May 8, 2012, 6:15:39 AM5/8/12
to Joran, ggp...@googlegroups.com
Hi again...

here is an update of my progress:

I used Joran's approach of interpolating (see below).
The plot is now working after some adaptations to my data structure.
There is still a little question concerning the plot (transparency) itself (see at the end).

1) My data frame included also some grouping variables
for facet-plotting. So, first I had to run the interpolation and
creation of the new data frame for upper and lower in
a loop.

2) As my original x data were highly skewed (lot of very small values, fewer
large values) the interpolation failed at the parts of very small values. Thus I used exp(log) in combination with seq to get a log-scaled sequence
for the new x values (and I increased the amount of points)

Here the example of the loop (over species and steps) and the log-scaled sequence:

# Get upper and lower for geom_ribbon
ls = list()
for(j in levels(df$species)){
for(i in levels(df$step)){
df1 <- df[(df$species==j & df$step==i & df$ci!="fit"),]

r <- range(df1$value)
xout <- exp(seq(log(r[1]), log(r[2]), length.out=100))
lower <- with(df1,approx(value[ci=="lwr"],y=abscount[ci=="lwr"],xout=xout,rule=2))$y
upper <- with(df1,approx(value[ci=="upr"],y=abscount[ci=="upr"],xout=xout,rule=2))$y

df2 <- data.frame(x=xout,lower=lower,upper=upper,species=j,step=i)
ls[[paste("ci.df2",j,i,sep="_")]] <- df2
}}
df3 <- as.data.frame(do.call(rbind, ls))

The resulting dataframe I then used in the ggplot command with facets (grouping variable = steps, facetting = species).


There is just one little question concerning the plot itself and the
transparency. When I use the ggplot-command as mentioned by Joran:

ggplot(df) +
geom_ribbon(data = df1,aes(x = xout,ymin = lower,ymax = upper),alpha = 0.5)
+ geom_line(aes(x=x,y=y,group = var))

...also the line is plotted with the transparency level alpha=0.5. How do
I change that, so that the ribbon is transparent but not the line which plots on top of the ribbon?

Best regards,

Johannes

-------- Original-Nachricht --------
> Datum: Mon, 7 May 2012 08:04:02 -0700 (PDT)
> Von: Joran <joran...@gmail.com>
> An: ggp...@googlegroups.com
> Betreff: Re: Plot band of uncertainty
> --
> You received this message because you are subscribed to the ggplot2
> mailing list.
> Please provide a reproducible example:
> https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2

Dennis Murphy

unread,
May 8, 2012, 8:12:05 AM5/8/12
to Johannes Radinger, ggp...@googlegroups.com
Hi:

In the absence of a reproducible example this is speculation, but
perhaps the following will work:

ggplot(df) +
geom_ribbon(data = df1,
aes(x = xout, ymin = lower, ymax = upper), alpha = 0.5) +
geom_line(aes(x=x,y=y,group = var)) +
geom_line(data = df1, aes(x = xout, y = lower)) +
geom_line(data = df1, aes(x = xout, y = upper))

Dennis
Reply all
Reply to author
Forward
0 new messages