partial use of ggplot graphs

77 views
Skip to first unread message

Ross Boylan

unread,
Aug 1, 2014, 5:05:35 PM8/1/14
to ggp...@googlegroups.com
I'm considering have a table where each row describes an effect, and one
cell in the row is a density plot of the estimated distribution of the
effect.

ggplot seems oriented toward producing free-standing graphs; is this
something it could do? How?

I think this differs from the usual output in two ways: the individual
graphs would be a small part of a page, and they might include only the
central plot area.

Thanks.
Ross Boylan

Doug Mitarotonda

unread,
Aug 1, 2014, 5:55:20 PM8/1/14
to Ross Boylan, ggp...@googlegroups.com
It sounds like you want `facet_grid`, but hard to tell without a MWE.
> --
> --
> 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/d/optout.

Ross Boylan

unread,
Aug 1, 2014, 6:03:27 PM8/1/14
to Doug Mitarotonda, ggp...@googlegroups.com
On Fri, 2014-08-01 at 14:55 -0700, Doug Mitarotonda wrote:
> It sounds like you want `facet_grid`, but hard to tell without a MWE.
I don't want ggplot to produce the whole table, just the individual
plots that would go in some of the cells. I suppose if I could produce
the whole column at once it would be convenient, but getting it line up
with the other rows seems likely to be more trouble than it's worth.

If MWE = mimimum working example, the problem is that I don't know how
to produce what I want, or even if it's possible.

From the document side, there would be a table and at each row of a
particular column there would be a directive to include a graphic file.

Ross
> --


Doug Mitarotonda

unread,
Aug 1, 2014, 6:06:30 PM8/1/14
to Ross Boylan, ggp...@googlegroups.com
Perhaps look at the `gridExtra ` package and see if that does what you need.

Dennis Murphy

unread,
Aug 1, 2014, 6:47:10 PM8/1/14
to Ross Boylan, Doug Mitarotonda, ggplot2
Like Doug, it's not clear to me what you really want. If you want to
produce densities at levels of a single factor or level combinations
of two factors, then faceting is what you probably want. OTOH, if you
want to place inset graphs at selected (spatial) locations, say on a
map, then you need a different type of solution. In a situation like
the latter case, it may be necessary to use the grid package directly,
generating the graphs as individual objects and positioning them
inside appropriately sized and positioned viewports. Your situation
sounds intermediate to the two scenarios outlined above, but without
some idea of the actual structure it's hard to recommend a single
course of action. I'll throw the ggsubplot package in as another
possibility, but I have no idea whether or not it would be helpful.

Dennis

Ross Boylan

unread,
Aug 1, 2014, 7:12:32 PM8/1/14
to Dennis Murphy, Doug Mitarotonda, ggplot2
On Fri, 2014-08-01 at 15:47 -0700, Dennis Murphy wrote:
> Like Doug, it's not clear to me what you really want.
OK, let me try a plain text version of the kind of result I would like:

====================================================================
Effect Sizes
====================================================================
Effect | Mean | Distribution
A | 0.5 | <graph1>
B | 0.1 | <graph2>
C | -0.1 | <graph3>
....
==================================================================

For each effect I have a bunch of simulated values, which together make
up the estimated distribution of the effect. The data source for each
effect is different. I want graph1, for example, to be a smoothed
density plot of the distribution of the effect values for A.

It would be desirable if each graph had the same scale and the reference
point (0) lined up.

> If you want to
> produce densities at levels of a single factor or level combinations
> of two factors, then faceting is what you probably want. OTOH, if you
> want to place inset graphs at selected (spatial) locations, say on a
> map, then you need a different type of solution.
I hope it's clearer now what I'm trying to do; it's not exactly either
of the possibilities you mention.

sparklines looks as if it's in the right direction, but the
documentation for it is pretty minimal.

The table itself will likely be in LaTeX, although ultimately everything
has to end up in MS Word.

My initial idea was that I'd produce a little file for each <graphN>; an
alternative would be to have a single image that I could use to file the
entire "Distribution" column.

Ross

Doug Mitarotonda

unread,
Aug 1, 2014, 8:01:21 PM8/1/14
to Ross Boylan, Dennis Murphy, ggplot2
Interesting concept but I imagine beyond the scope of all packages I know of. I would probably use a combination of `knitr` and `xtable` to get the result you are looking for.

Ista Zahn

unread,
Aug 1, 2014, 9:25:17 PM8/1/14
to Doug Mitarotonda, ggplot2, Dennis Murphy, Ross Boylan
I meant to send this suggestion to the whole list, but my phone
defaults to reply rather than reply-all.

What Keith is asking for is called a spark table, and they can be
produced using the sparkTable package. An introductory vignette can be
found at http://publik.tuwien.ac.at/files/PubDat_228663.pdf.

Here is a quick example similar to Keith's ASCII sketch:

library(reshape2)

mtcWide <- dcast(data.frame(car = rownames(mtcars),
mtcars[c("gear", "mpg")]),
... ~ gear, value.var = "mpg")

names(mtcWide) <- paste("gears", names(mtcWide))

library(sparkTable)
summaryST(mtcWide[-1],
outputType="html",
filename = "mtcars",
hist=TRUE,
boxplot=FALSE,
min=FALSE,
quantile=FALSE,
median=FALSE,
mean=TRUE,
max=FALSE)


Best,
Ista

Ross Boylan

unread,
Aug 1, 2014, 11:33:18 PM8/1/14
to Ista Zahn, Doug Mitarotonda, ggplot2, Dennis Murphy
Thank you for the example. I'm Ross, not Keith!

What I want may have a little more adornment than seems usual for a
spark table; at least judging by some examples they don't have any
reference lines or tick marks.

Also, for those who may offer other suggestions, I am not looking for a
solution that produces the entire table. I just need to produce the
graphics. My plan is to output the LaTeX for the rest of the table.

Ross

Dennis Murphy

unread,
Aug 2, 2014, 2:17:02 AM8/2/14
to Ross Boylan, ggplot2
I appreciate the idea of spark tables, but my limited interaction with
them was to compactly compare time series data in a dashboard. I don't
think they were meant to compare distributions in such a limited
space, but I could be wrong.

One way to get what you want in ggplot2 could be to facet by treatment
and to label the mean effect in each facet. By default, faceting
produces the same x- and y-limits. In the code below, I expand the
x-limits somewhat to provide enough room for the labels.

DF <- data.frame(trt = factor(rep(LETTERS[1:3], each = 100)),
y = rnorm(300, mean = rep(c(0.5, 0.1, -0.1), each = 100),
sd = 0.1))

library(plyr)
library(ggplot2)

fx <- ddply(DF, "trt", summarise, y = round(mean(y), 2))
fx$lab <- paste0("Effect: ", fx$y)

# Treatments as facet labels, effects as annotation
ggplot(DF, aes(x = y)) +
theme_bw() +
geom_density(fill = "blue", color = NA, alpha = 0.5) +
geom_vline(xintercept = 0, color = "grey30") +
labs(x = "Effect", y = "Density") +
xlim(-0.5, 1) +
geom_text(data = fx, aes(x = -0.5, y = 4, label = lab), hjust = 0) +
facet_wrap(~ trt, ncol = 1)



An alternative approach, although not particularly ideal, is to add
the treatments and effects as labels in each density plot. Here's how
it might work as a first draft on the above toy example, although with
more groups you want a more programmatic solution than this.



p1 <- ggplot(subset(DF, trt == "A"), aes(x = y)) +
theme_bw() +
geom_density(fill = "blue", color = NA, alpha = 0.5) +
geom_vline(xintercept = 0, color = "grey30") +
labs(x = NULL, y = "") +
xlim(-1.5, 1) +
geom_text(x = -1.25, y = 4, label = "Treatment") +
geom_text(x = -0.75, y = 4, label = "Effect") +
geom_text(x = -1.25, y = 2, label = "A") +
geom_text(x = -0.75, y = 2, label = fx[1, "y"]) +
theme(axis.text.x = element_blank())

p2 <- ggplot(subset(DF, trt == "B"), aes(x = y)) +
theme_bw() +
geom_density(fill = "blue", color = NA, alpha = 0.5) +
geom_vline(xintercept = 0, color = "grey30") +
labs(x = NULL, y = "") +
xlim(-1.5, 1) +
geom_text(x = -1.25, y = 2, label = "B") +
geom_text(x = -0.75, y = 2, label = fx[2, "y"]) +
theme(axis.text.x = element_blank())

p3 <- ggplot(subset(DF, trt == "C"), aes(x = y)) +
theme_bw() +
geom_density(fill = "blue", color = NA, alpha = 0.5) +
geom_vline(xintercept = 0, color = "grey30") +
labs(x = "Effect", y = "") +
xlim(-1.5, 1) +
geom_text(x = -1.25, y = 2, label = "C") +
geom_text(x = -0.75, y = 2, label = fx[3, "y"])

library(gridExtra)
grid.arrange(p1, p2, p3, ncol = 1)

A third approach would be to create a gridTable of the appropriate
size for the treatments and effect along with the initial ggplot (sans
the annotation), each saved to an object. You might then do something
like

grid.arrange(my_grid_table, my_faceted_ggplot, nrow = 1)

with appropriate sizing in the x-direction, to generate a side-by-side
table with corresponding densities. See ?grid.arrange for further
details.

If any of these options appeal to you (and they may not), you'll still
need to fiddle with the size and type of graphic to export to your
Word document. This example is simply to illustrate different
possibilities with ggplot2. Your real example may contain far more
levels, enough so to make these illustrations impractical for your use
case. In my example, I also took the label positions from a
preliminary view of the graph; if you want a more programmatic
solution, you'll have to DIY.

Dennis

Ista Zahn

unread,
Aug 2, 2014, 9:25:20 AM8/2/14
to Ross Boylan, Doug Mitarotonda, ggplot2, Dennis Murphy
Sorry Ross, I'm not sure how I got your name mixed up.

You can certainly construct the graphs and insert them into a table
yourself, perhaps something along the lines of

d_ply(mtcars, "gear",
function(x) {
p <-ggplot(x, aes(x = mpg)) +
geom_density(fill = "grey60") +
scale_x_continuous(expand = c(.025, 0)) +
scale_y_continuous(expand = c(.025, 0)) +
theme_minimal()
gt <- ggplot_gtable(ggplot_build(p))
ge <- subset(gt$layout, name == "panel")
png(paste(unique(x$gear), "png", sep="."),
width = 80,
height = 60)
grid.draw(gt[ge$t:ge$b, ge$l:ge$r])
dev.off()
}
)


See http://stackoverflow.com/questions/14313285/ggplot2-theme-with-no-axes-or-grid

You will probably want to take steps to ensure that the axes are the
same, and possibly to include axis ticks (though I don't recommend
that).

Best,
Ista
Reply all
Reply to author
Forward
0 new messages