I need to reproduce a graph similar to the attached image. I hope to use the graphic to compare confidence intervals of the difference between proportions. How can I produce the attached graphic using R? Any pointers in the right direction would be appreciated.
-
1this question seems a little too vague. Do you want to do something with *quantitative data*? Otherwise, are you looking for `?arrows`, `?rect`, ... ? or `?confint`? or `?binom.test`? – Ben Bolker Dec 08 '12 at 03:02
-
1A better question would be if you had attempted this, and run into a specific problem along the way. – joran Dec 08 '12 at 03:51
-
1@Aaron: I think you will find that the energetic answers" expect you to provide a dataset in R code before they dive in and attempt to rescue you from the swiRling wateRs that torment the R noob. Many of us think dooing all of your project for you is asking too much. – IRTFM Dec 08 '12 at 04:54
-
1Cool question, waiting for data. http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Brandon Bertelsen Dec 08 '12 at 04:59
2 Answers
Without context and a reproducible example it is hard to give a good answer. But I think the plot is interesting.
Here my attempt with ggplot2. I still have some problem with alpha layer , but the main idea of the plot is here.
Some data
structure(list(scen = 1:6,
name = c("I", "II", "III", "IV", "V","VI"),
ymin = c(0.06, -0.102, 0.487, 0.116, -0.436, 0.021),
ymax = c(-0.231,0.135, 0.117, 0.338, -0.347, -0.025)),
.Names = c("scen", "name", "ymin", "ymax"),
row.names = c(NA, 6L),
class = "data.frame")
The data look like this
dat
scen name ymin ymax y
1 1 I 0.060 -0.231 I
2 2 II -0.102 0.135 II
3 3 III 0.487 0.117 III
4 4 IV 0.116 0.338 IV
5 5 V -0.436 -0.347 V
6 6 VI 0.021 -0.025 VI
This is the result
theme_new <- theme_set(theme_bw())
p <- ggplot(data=dat) +
geom_segment(aes(x=ymin,y=scen,xend=ymax,yend=scen),
arrow=arrow(length=unit(0.3,"cm"),
ends='both'),size=1)
p <- p+ geom_rect(xmin=max(dat$ymin)/2,
xmax=min(dat$ymax)/2,
ymin=0,
ymax=max(dat$scen)+1,
alpha=0.2,fill='grey')
p <- p + geom_text(aes(x=(ymin+ymax)/2,
y=scen+0.2,label =name),size=6)
p<- p + coord_cartesian(ylim=c(0,max(dat$scen)+3))+
xlab(expression(P[1]-P[0]))+
theme(
axis.ticks = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_blank(),
axis.title.x = element_text(face="bold", size=20))
p <- p + geom_vline(linetype ='dashed',
xintercept = mid.dash)
p <- p + geom_text(aes(x= mid.dash,
y = max(dat$scen)+2,
label="Zone of Indifference",
color="NA*"),rotate=180)
p <- p + theme(legend.position = "none")
p

- 119,832
- 17
- 199
- 261
-
1the `[po]` etc need to be outside the quotes. e.g. `"hi",beta[0],"bye"` if this helps the OP – user1317221_G Dec 08 '12 at 11:37
-
1@agstudy This answer goes above and beyond--thank you. I will certainly be able to use this approach with my own dataset. – Borealis Dec 08 '12 at 15:12
-
-
Great answer. Changing the order in which you make the layers will 'fix' the alpha problem (if I understand correctly what you mean by that): print the arrow layer after you make the 'zone of indifference' layer: your first ``geom_segment()`` after your first ``geom_rect()``. (I'm sure you know that now, this answer is from... 2012!) – PatrickT Mar 28 '18 at 05:39
-
@PatrickT thank you. Yes I know that of course. Fill free to change the answer if you want to make it better. – agstudy Mar 28 '18 at 07:46
-
@agstudy, I ended up posting a follow-up answer as the most important edits were minor and the rest was just fooling around trying to replicate the textbook figure, with only partial success (the curly brace a major fail, the font of P1-P0 not very good either). I should have used ``tikzDevice``... – PatrickT Mar 28 '18 at 17:54
This is a follow-up on agstudy's answer (please upvote his answer). It was too long for a comment and too different to justify my editing his answer. Also minor things will still require tweaking to look like a textbook figure. Next time I do this sort of thing, I will try to use tikzDevice
to get the font face, subscripts, etc. to work properly. I have added the curly braces, but 1) I prefer the figure without it and 2) I couldn't make ggsave()
to use the correct font and the braces looked bad in the PDF (I saved the image as PNG with RStudio
's export tool).
## Confidence interval segments with ggplot
# https://stackoverflow.com/questions/13773806/
# Data
d = structure(list(index = 1:6, name = c("I", "II", "III", "IV",
"V", "VI"), xmin = c(0.06, -0.102, 0.487, 0.116, -0.436, 0.121
), xmax = c(-0.231, 0.135, 0.117, 0.338, -0.347, -0.055)), .Names = c("index",
"name", "xmin", "xmax"), row.names = c(NA, 6L), class = "data.frame")
# Plot Data
x1 = -0.5 # lower limit of x-axis
x2 = +0.5 # upper limit of x-axis
y1 = -0.5 # lower limit of y-axis
y2 = max(d$index)+2 # upper limit of y-axis
z0 = 0 # center of indifference zone
z1 = -0.25 # lower limit of indifference zone
z2 = +0.25 # upper limit of indifference zone
z3 = min(d$index)-0.5 # lower limit of indifference zone
z4 = max(d$index)+0.5 # lower limit of indifference zone
df = cbind(d, data.frame(z0 = z0, z1 = z1, z2 = z2, x1 = x1, x2 = x2, z3 = z3, z4 = z4))
# Plot confidence intervals
library(ggplot2)
ggplot(data = df) +
# extend the y-axis limits to make room for label
coord_cartesian(xlim = c(x1, x2), ylim = c(y1, y2)) +
# zone of indifference layer:
geom_rect(aes(xmin = z1, xmax = z2, ymin = z3, ymax = z4),
alpha = 0.5,
fill = "grey") +
# vertical line to indicate the true mean
geom_segment(aes(x = z0, xend = z0, y = z3, yend = z4), linetype = 2) +
# confidence intervals with arrows:
geom_segment(aes(x = xmin, xend = xmax, y = index, yend = index),
arrow = arrow(length = unit(0.3, "cm"), ends = "both"), size = 1) +
# labels above the confidence intervals:
geom_text(aes(x = (xmin+xmax)/2, y = index+0.2, label = name), size = 4) +
# make curly bracket - tweak vjust, hjust and size manually to center it!
geom_text(aes(x = z0, y = z4, label = "{"), angle = 270, vjust = 0.38, hjust = 1, size = 80, fontface = "bold", family = 'Helvetica Neue UltraLight') +
# label above the indifference layer
annotate("text", x = z0, y = y2, hjust = 0.5, vjust = 1,
label = "Zone of Indifference\n", fontface = "bold", size = 5) +
# label below the indifference layer
annotate("text", x = z0, y = y1, hjust = 0.5,
label = "P[1]-P[0]", parse = TRUE, # bold.italic does not survive parse=TRUE
family = "Times", fontface = "bold.italic", size = 5) +
# tweak x-axis and ticks | get rid of default axis, ticks, labels, etc.
scale_x_continuous(breaks = c(x1, x2),
labels = c("-x", "+x")) + # set breaks + labels
#theme_void() + # should have worked, but...
theme(panel.background = element_rect(fill = NA, colour = NA)) +
# insert tweaked horizontal x-axis + ticks
theme(panel.grid = element_blank()) +
theme(panel.border = element_blank()) + # may want to keep
theme(axis.line.y = element_blank()) +
theme(axis.title.y = element_blank()) +
theme(axis.ticks.y = element_blank()) +
theme(axis.text.y = element_blank()) +
theme(axis.line.x = element_line(size = 1, linetype = "solid")) +
theme(axis.title.x = element_blank()) +
theme(axis.ticks.x = element_line(size = 1)) +
theme(axis.ticks.length = unit(.3, "cm")) +
theme(axis.text.x = element_text(size = 14))
ggsave("ggplot-ci-indifference.pdf", device = cairo_pdf)
## the curly-brace does not print properly!
It would be prettier without the curly braces.
Credit: for the curly braces, see: How to add braces to a graph?

- 10,037
- 9
- 76
- 111