[R] bar plot with non-zero starting level

7 views
Skip to first unread message

Xianwen Chen

unread,
May 18, 2013, 7:19:32 PM5/18/13
to r-h...@r-project.org
Hi,

I want to plot grouped bars to compare 95% confidence interval estimates
from two models. Each bar represents a 95% confidence interval estimate
of a coefficient from one of the two models. Each group represents
confidence interval estimates of the same coefficient from the two models.

I think such a bar plot will nicely present whether 95% confidence
interval estimates of the same coefficient from the two models overlap.
All these confidence intervals do not start from the x axis.

I searched bar plot examples on Google. I found methods to plot bars in
groups by barplot(). I could only specify one offset for all confidence
interval estimates of the same model. I could not individually specify
an offset for each confidence interval estimate. Can someone please help
me on how I may proceed with individual offset for each of the bar in
the plot?

Thank you in advance.

Kind regards,

Xianwen

______________________________________________
R-h...@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.

Jim Lemon

unread,
May 19, 2013, 7:17:43 AM5/19/13
to Xianwen Chen, r-h...@r-project.org
On 05/19/2013 09:19 AM, Xianwen Chen wrote:
> Hi,
>
> I want to plot grouped bars to compare 95% confidence interval estimates
> from two models. Each bar represents a 95% confidence interval estimate
> of a coefficient from one of the two models. Each group represents
> confidence interval estimates of the same coefficient from the two models.
>
> I think such a bar plot will nicely present whether 95% confidence
> interval estimates of the same coefficient from the two models overlap.
> All these confidence intervals do not start from the x axis.
>
> I searched bar plot examples on Google. I found methods to plot bars in
> groups by barplot(). I could only specify one offset for all confidence
> interval estimates of the same model. I could not individually specify
> an offset for each confidence interval estimate. Can someone please help
> me on how I may proceed with individual offset for each of the bar in
> the plot?
>
Hi Xianwen,
It seems that you want to line up either one or both of the estimates
for each coefficient and then display the confidence intervals as bars
around the estimates. If so, your ordinate (y-axis) won't be very
interpretable unless you add one for each pair of coefficients. What I
would initially suggest is that you display the coefficient values along
a horizontal line and use "error bars" to show the confidence intervals.
Here is an example:

coef<-c(3.6,3.2,5.7,6.0,1.2,1.3)
CIs<-c(1.2,1.4,2.7,2.6,3.1,2.9)
plot(0,xlim=c(0.5,3.5),ylim=range(c(-CIs,CIs)),type="n",
xlab="Coefficients",ylab="95% confidence intervals",xaxt="n")
axis(1,at=c(0.8,1.2,1.8,2.2,2.8,3.2),
labels=c("A1","A2","B1","B2","C1","C2"))
abline(h=0)
library(plotrix)
dispersion(c(0.8,1.2,1.8,2.2,2.8,3.2),rep(0,6),ulim=CIs,interval=TRUE)
boxed.labels(c(0.8,1.2,1.8,2.2,2.8,3.2),0,coef)

Jim

Xianwen Chen

unread,
May 20, 2013, 10:54:37 AM5/20/13
to Jim Lemon, r-h...@r-project.org
Hi Jim,

Thank you for the suggestion. I think overlapped rectangles will well
present the message. I'm now trying ggplot2.

Here is the code:

require(ggplot2)
rect_MNL_Delta <- data.frame(
xmin <- c(1, 3, 5, 7, 9, 11, 13),
xmax <- xmin + 1,
ymin <- c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694,
-.44146, 1.45884),
ymax <- c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564, 3.08630,
3.39865)
)
rect_GMNL <- data <- data.frame(
xmin <- c(1, 3, 5, 7, 9, 11, 13),
xmax <- xmin + 1,
ymin <- c(17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95),
ymax <- c(20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81)
)

ggplot() +
geom_rect(data = rect_MNL_Delta, aes(xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax), fill = "blue", alpha = 0.1) +
geom_rect(data = rect_GMNL, aes(xmin = xmin, xmax = xmax, ymin
= ymin, ymax = ymax), fill = "green", alpha = 0.1)

The problem is that the second geom_rect() fully covered the first
geom_rect(), instead of overlapping. Another issue is that I don't know
how to set labels on x-axis, instead of the current ticks. I would like
to have for instance 'Farmed cod' under the first rectangle.

Can you provide me some hints? Thank you.

Kind regards,

Xianwen

Jim Lemon

unread,
May 20, 2013, 6:40:34 PM5/20/13
to Xianwen Chen, R-h...@r-project.org
Hi Xianwen,
The problem with the overlapping is in the last two lines. These should
read:

geom_rect(data = rect_MNL_Delta, aes(xmin =
rect_MNL_Delta$xmin, xmax = rect_MNL_Delta$xmax, ymin =
rect_MNL_Delta$ymin, ymax = rect_MNL_Delta$ymax), fill = "blue", alpha =
0.1) +
geom_rect(data = rect_GMNL, aes(xmin = rect_GMNL$xmin, xmax =
rect_GMNL$xmax, ymin = rect_GMNL$ymin, ymax = rect_GMNL$ymax), fill =
"green", alpha = 0.1)

I am not terribly familiar with ggplot, but you should be able to get
custom tick labels on your horizontal axis. I have to go out now, but
when I return I'll have a look at the "scale" functions, as I think this
is hiding in there.

Xianwen Chen

unread,
May 22, 2013, 11:06:22 AM5/22/13
to Jim Lemon, R-h...@r-project.org
Hi Jim,

Thank you very much. I have started another conversation in the ggplot
list. My current code is

plot_data <- data.frame(

xmin = c(1, 1.5, 3, 3.5, 5, 5.5, 7, 7.5, 9, 9.5, 11, 11.5, 13, 13.5)

, ymin = c(16.7026, 17.20, 14.9968, 16.32, 16.0630, 15.86, 17.7510, 18.12,
-5.01694, -8.86, -.44146, -0.03, 1.45884, 0.95)

, ymax = c(21.1602, 20.12, 18.7613, 18.60, 19.1367, 18.14, 23.6730, 22.29,
2.26564, 3.03, 3.08630, 3.57, 3.39865, 2.81)

, model = rep(c("MMNL", "GMNL"), 7)

)


plot_data$"xmax" <- plot_data$"xmin" + 1


WTP_plot_parallel <- ggplot(plot_data, aes(xmin = xmin, xmax = xmax, ymin
= ymin, ymax = ymax, fill = model)) +

geom_rect(alpha = .8) +

scale_x_continuous(breaks = c(1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5)

, labels = c("Wild cod", "Farmed cod", "Farmed salmon", "Wild monk",
"Farmed pangasius", "MSC label", "AB label")) +

scale_y_continuous(name = "Confidence Interval of WTP Estimators (EUR/KG)")
+

theme(axis.text.x = element_text(angle = 45, hjust = .5, vjust = .5)) +

scale_fill_manual("Model", values = c(grey(0.1), grey(0.7)))


WTP_plot_parallel

I'm still working on some details. If you are interested, I'll keep you in
the loop.

Kind regards,
Xianwen
--
Xianwen Chen <xnw...@gmail.com>
Graduate student of economics
Norwegian University of Life Sciences
[[alternative HTML version deleted]]

Xianwen Chen

unread,
May 22, 2013, 1:11:36 PM5/22/13
to Dennis Murphy, r-h...@r-project.org, Ito, Kaori (Groton), ggp...@googlegroups.com
Hi Dennis,

Thank you for your constructive advice on plotting CIs in point ranges. I
combined the advices from you, Jim, Kaori, and bosie (from IRC) and my own
research and produced the following figure:

WTP_labels <- c("Wild cod", "Farmed cod", "Farmed salmon", "Wild monk",
"Farmed pangasius", "MSC label", "AB label")

plot_data <- data.frame(
xmin = c(1, 1.5, 3, 3.5, 5, 5.5, 7, 7.5, 9, 9.5, 11, 11.5, 13, 13.5)
, ymin = c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694, -.44146,
1.45884
, 17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95)
, ymax = c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564, 3.08630,
3.39865
, 20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81)
, ymean = c(18.93, 16.88, 17.60, 20.71, -1.38, 1.32, 2.43
, 18.66, 17.46, 17.00, 20.20, -2.92, 1.77, 1.88)
, model = rep(c("MMNL", "GMNL"), each = 7)
, id = factor(WTP_labels, levels = WTP_labels)
)

plot_data$"xmax" <- plot_data$"xmin" + 1

WTP_plot_pointrange <- ggplot(plot_data, aes(x = id, y = ymean, color =
model)) +
theme_bw() +
# geom_hline(yintercept = 0, color = grey(0.1)) +
geom_pointrange(aes(ymin=ymin, ymax=ymax)
, size = .6
, position = position_dodge(width = 0.4)) +
labs(x = ""
, y = "Confidence interval of WTP estimators (EUR/KG)") +
scale_color_manual(values = c(grey(0.5), grey(0.8))) +
coord_flip()

WTP_plot_pointrange

Kind regards,
Xianwen
--
Xianwen Chen <xnw...@gmail.com>
Graduate student of economics
Norwegian University of Life Sciences


On Tue, May 21, 2013 at 1:05 AM, Dennis Murphy <djm...@gmail.com> wrote:

> Hi:
> Assignment of objects within data.frame() is rather fraught with
> danger, because they're being assigned in the environment in which the
> data.frame is created. It's safer to use the = syntax inside
> data.frame() because that's the convention for assignment/definition
> inside a function call, but in that case you can't define a new
> variable in terms of another created in the same data.frame() call. It
> needs to be done this way:
>
> rect_MNL_Delta <- data.frame(
> xmin = c(1, 3, 5, 7, 9, 11, 13),
> ymin = c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694,
> -.44146, 1.45884),
> ymax = c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564,
> 3.08630,3.39865)
> )
> # Assign the new variable
> rect_MNL_Delta$xmax <- rect_MNL_Delta$xmin + 1
>
> rect_GMNL <- data.frame(
> xmin = c(1, 3, 5, 7, 9, 11, 13),
> ymin = c(17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95),
> ymax = c(20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81)
> )
> rect_GMNL$xmax <- rect_GMNL$xmin + 1
>
>
> You can fill in the pieces, but I just modified a few of Kaori's
> suggestions to provide a slightly different look. I hate angled text
> on the x-axis, so suggest that you rotate the plot so that these end
> up on the y-axis instead. Since you're using purples and greens, they
> tend to show up better on a white background rather than the default
> gray:
>
> mylabs <- c("Wild cod", "Farmed cod", "Farmed salmon", "Wild monk",
> "Farmed pangasius", "MSC label", "AB label")
>
> ggplot() +
> theme_bw() +
> geom_rect(data = rect_MNL_Delta, aes(xmin = xmin - 0.5,
> xmax = xmax - 0.5,
> ymin = ymin, ymax = ymax),
> fill = "blue") +
> geom_rect(data = rect_GMNL, aes(xmin = xmin - 0.5, xmax = xmax - 0.5,
> ymin = ymin, ymax = ymax),
> fill = "green") +
> scale_x_continuous(breaks = c(1, 3, 5, 7, 9, 11, 13),
> labels = mylabs) +
> coord_flip()
>
> Notice that I subtracted 0.5 from both xmin and xmax so that the bar
> would be centered at the label. I'd suggest making a vector of labels
> outside the ggplot() call and then pull it in during the geom_text()
> call (see the mylabs object and its call within scale_x_continuous()
> ).
>
> Here's another way to approach the problem, both from a data and a
> plotting perspective. In reality, you have a 'fish type' factor; let's
> call it id and redefine the data frames as follows, 'starting from
> scratch':
>
> mylabs <- c("Wild cod", "Farmed cod", "Farmed salmon", "Wild monk",
> "Farmed pangasius", "MSC label", "AB label")
> rect_MNL_Delta <- data.frame(
> id = factor(mylabs, levels = mylabs),
> ymin = c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694,
> -.44146, 1.45884),
> ymax = c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564,
> 3.08630,3.39865)
> )
>
> rect_GMNL <- data.frame(
> id = factor(mylabs, levels = mylabs),
> ymin = c(17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95),
> ymax = c(20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81)
> )
>
> One way to reproduce your plot would be as follows, using
> geom_segment() in place of geom_rect():
>
> ggplot() + theme_bw() +
> geom_segment(data = rect_MNL_Delta,
> aes(x = id, xend = id, y = ymin, yend = ymax),
> size = 10, color = "blue", alpha = 0.5) +
> geom_segment(data = rect_GMNL,
> aes(x = id, xend = id, y = ymin, yend = ymax),
> size = 10, color = "green", alpha = 0.5) +
> labs(x = "", y = "Confidence interval of WTP estimators (EUR/KG)") +
> coord_flip()
>
> Another approach, which I believe would be more appropriate given that
> you want to compare CIs from different models on the same set of
> species, could be done by combining the two data frames and using
> geom_pointrange() on each model to visualize the CIs:
>
> GMNL <- rbind(rect_MNL_Delta, rect_GMNL)
> GMNL$Model <- rep(c("MNL", "GMNL"), each = 7)
> GMNL$mean <- with(GMNL, (ymin + ymax)/2)
>
> ggplot(GMNL, aes(x = id, y = mean, color = Model)) +
> theme_bw() +
> geom_hline(yintercept = 0, color = "gray40") +
> geom_pointrange(aes(ymin = ymin, ymax = ymax),
> size = 1,
> position = position_dodge(width = 0.4)) +
> labs(x = "", y = "Confidence interval of WTP estimators (EUR/KG)") +
> scale_color_manual(values = c("blue", "orange")) +
> coord_flip()
>
> It's not necessarily 'better' than your original plot, but it's an
> alternative approach that allows for direct comparison of the two CIs
> for each id/species/whatever it is ;)
>
> HTH,
> Dennis
>
> On Mon, May 20, 2013 at 1:27 PM, Xianwen Chen <xnw...@gmail.com> wrote:
> > Hi Kaori,
> >
> > どうもありがとう! You helped me greatly. I spent two days digging into numerous
> web
> > pages and documents. It was wonderful to get your hints! Just one
> question,
> > why did you use '=' instead of '<-' inside 'data.frame()'?
> >
> > Based on your suggestion, I added Y-axis label and also legends. Because
> > this is a plot for a research article, I have to use black, white, and
> gray.
> > In the following codes, I use two scales of gray. The problem kicks when
> the
> > darker gray totally covers the lighter gray, it is impossible to see
> where
> > the lighter gray is. To clearly illustrate the problem, I put on an
> > identical plot, but with colors at http://i.imgur.com/aehb0dx.jpg
> > Here is the code with colors in gray scales:
> >
> >
> > rect_MNL_Delta <- data.frame(
> > xmin = c(1, 3, 5, 7, 9, 11, 13),
> > xmax = c(2, 4, 6, 8, 10, 12, 14),
> >
> > ymin = c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694, -.44146, 1.45884),
> > ymax = c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564, 3.08630,3.39865),
> > f = 'MNL'
> >
> > )
> > rect_GMNL <- data.frame(
> > xmin = c(1, 3, 5, 7, 9, 11, 13),
> > xmax = c(2, 4, 6, 8, 10, 12, 14),
> >
> > ymin = c(17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95),
> > ymax = c(20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81),
> > f = 'GMNL'
> > )
> >
> > WTP_plot = ggplot() +
> > geom_rect(data = rect_MNL_Delta, aes(xmin = xmin, xmax = xmax, ymin =
> ymin,
> > ymax = ymax, fill = grey(0.3)), alpha = 0.5) +
> > geom_rect(data = rect_GMNL, aes(xmin = xmin, xmax = xmax, ymin = ymin,
> ymax
> > = ymax, fill = grey(0.6)), alpha = 0.5) +
> > scale_fill_manual(name = "Model", breaks = c(grey(0.3), grey(0.6)),
> values
> > =c(grey(0.3), grey(0.6)), labels = c("MNL", "GMNL")) +
> > scale_x_continuous(breaks=c(1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5),
> > labels=c("Wild cod", "Farmed cod","Farmed salmon","Wild monk","Farmed
> > pangasius","MSC label","AB label")) +
> > scale_y_continuous(name = "Confidence Interval of WTP estimators
> (EUR/KG)")
> > +
> > theme(axis.text.x = element_text(angle=45, hjust=.5, vjust=0.5))
> >
> > WTP_plot
> >
> > Is there some way to address this issue? Perhaps same color but with
> > different texture, or pattern? Any thought on this would be highly
> > appreciated. Thank you!
> >
> > Kind regards,
> >
> > Xianwen
> >
> >
> >
> > Ito, Kaori (Groton) wrote:
> >>
> >> How about this? I changed "<-" to "=" in the data.frame.
> >> You have continuous variables on x so I used scale_x_continuous for
> >> changing the ticks and adding labels. You can modify angle, size, etc
> with
> >> theme.
> >>
> >>
> >> rect_MNL_Delta<- data.frame(
> >> xmin = c(1, 3, 5, 7, 9, 11, 13),
> >> xmax = xmin + 1,
> >> ymin = c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694,
> -.44146,
> >> 1.45884),
> >> ymax = c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564,
> >> 3.08630,3.39865)
> >> )
> >> rect_GMNL<- data.frame(
> >> xmin = c(1, 3, 5, 7, 9, 11, 13),
> >> xmax = xmin + 1,
> >> ymin = c(17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95),
> >> ymax = c(20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81)
> >> )
> >>
> >> ggplot() +
> >> geom_rect(data = rect_MNL_Delta, aes(xmin = xmin, xmax = xmax,
> >> ymin = ymin, ymax = ymax), fill = "blue", alpha = 0.1) +
> >> geom_rect(data = rect_GMNL, aes(xmin = xmin, xmax = xmax,
> ymin =
> >> ymin, ymax = ymax), fill = "green", alpha = 0.1) +
> >> scale_x_continuous(breaks=c(1, 3, 5, 7, 9, 11, 13),
> >> labels=c("Farmed cod","text","text","text","text","text","text")) +
> >> theme(axis.text.x = element_text(angle=90, hjust=1,
> vjust=0.5))
> >>
> >>
> >>
> >> -----Original Message-----
> >> From: ggp...@googlegroups.com [mailto:ggp...@googlegroups.com] On
> Behalf
> >> Of Xianwen Chen
> >> Sent: Monday, May 20, 2013 11:35 AM
> >> To: ggp...@googlegroups.com
> >> Subject: Re: [R] bar plot with non-zero starting level
> >>
> >> Hi,
> >>
> >> I want to overlap two rectangular plots. Here is my code:
> >>
> >> require(ggplot2)
> >> rect_MNL_Delta<- data.frame(
> >> xmin<- c(1, 3, 5, 7, 9, 11, 13),
> >> xmax<- xmin + 1,
> >> ymin<- c(16.7026, 14.9968, 16.0630, 17.7510, -5.01694,
> >> -.44146, 1.45884),
> >> ymax<- c(21.1602, 18.7613, 19.1367, 23.6730, 2.26564, 3.08630,
> >> 3.39865)
> >> )
> >> rect_GMNL<- data<- data.frame(
> >> xmin<- c(1, 3, 5, 7, 9, 11, 13),
> >> xmax<- xmin + 1,
> >> ymin<- c(17.20, 16.32, 15.86, 18.12, -8.86, -0.03, 0.95),
> >> ymax<- c(20.12, 18.60, 18.14, 22.29, 3.03, 3.57, 2.81)
> >> )
> >>
> >> ggplot() +
> >> geom_rect(data = rect_MNL_Delta, aes(xmin = xmin, xmax = xmax,
> >> ymin = ymin, ymax = ymax), fill = "blue", alpha = 0.1) +
> >> geom_rect(data = rect_GMNL, aes(xmin = xmin, xmax = xmax, ymin
> >> = ymin, ymax = ymax), fill = "green", alpha = 0.1)
> >>
> >> The problem is that the second geom_rect() fully covered the first
> >> geom_rect(), instead of overlapping with transparency.
> >>
> >> Another issue is that I don't know how to set labels on x-axis, instead
> >> of the current ticks. I would like to have for instance 'Farmed cod'
> >> under the first rectangle.
> >>
> >> Can you provide me some hints? Thank you.
> >>
> >> Kind regards,
> >>
> >> Xianwen
> >>
> >> Jim Lemon wrote:
> >>>
> > --
> > --
> > 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
> >
> > --- You received this message because you are subscribed to the Google
> > Groups "ggplot2" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to ggplot2+u...@googlegroups.com.
> > For more options, visit https://groups.google.com/groups/opt_out.
> >
> >
>

[[alternative HTML version deleted]]

Reply all
Reply to author
Forward
0 new messages