I'm currently working on section for the ggplot2 book about writing
functions that create ggplot2 plots. I'm having a bit of a hard time
thinking about what I should say (or even if it's useful enough to
include in the book), so I was wondering if you'd written a function
that creates ggplot2 plots, if you would mind sending it to me for
some inspiration.
Thanks!
Hadley
You will always be ok provided all of the data you provide in a data
frame. If you use ggplot you should almost always be ok, unless you
are using local variables in an aes call (which is theoretically not
allowed but I can't figure out how to detect it so I can issue an
error)
> The following function (package constants on r-forge/photonics) takes a
> data.frame, does some trivial conversion, and outputs a list containing a
> ggplot. A few bottlenecks I've encountered:
>
> - in an interactive session, calling the result of this function will print
> the plot whether I want it or not. I'm not sure how to make it more
> invisible.
What I would do here is split your function into two pieces - one that
creates the data frame and one that produces the plot. This makes it
much easier for other people to build on top of your efforts if they
don't want to use any part of the plot you provide (at least they can
get the data separately from the plot in your function, which is
better than most of base R)
So I'd suggest material2plot just returns a list of the two data
frames with class = "material2plot". You then write a
plot.material2plot that produces the plot. Your example would then
become:
gold <- fit.material("AuJChristy", range=c(0.4, 1), draw=F)
material2plot(gold$fine)->testFine
plot(testFine)
plot(testFine) + geom_point(aes(colour = variable))
> - the variable names in the ggplot call are all hard-wired because I don't
> know how to pass them as arguments. A few tips on using substitute, quote,
> bquote, eval, deparse ... would be very useful I think.
Ok - aes_string is probably the way to go here. aes_string("x",
"myvar") is equivalent to aes(x, myvar), with the obvious difference
that it's much much much easier to work with strings than expressions.
> - a slight issue with plotmath type labels not working in strips, but this
> is not relevant here
On my to do list ;)
Hadley
Having actually tried that out, I now think it's bad advice. Here's
what's currently going into the book:
As mentioned in the previous section, you definitely want to separate
your plotting code into a function that does any data transformations
and manipulations and a function that creates the plot. Generally,
your plotting function should do no data manipulation, just create a
plot. See the following example for one way to create a parallel
coordinates function.
% INTERWEAVE
%
% pcp_data <- function(df) {
% numeric <- laply(df, is.numeric)
% # Rescale numeric columns
% df[numeric] <- colwise(range01)(df[numeric])
% # Add row identified
% df$.row <- rownames(df)
% # Melt, using non-numeric variables as id vars
% dfm <- melt(df, id = c(".row", names(df)[!numeric]))
% # Add pcp to class of the data frame
% class(dfm) <- c("pcp", class(dfm))
% dfm
% }
% pcp <- function(df, ...) {
% df <- pcp_data(df)
% ggplot(df, aes(variable, value)) + geom_line(aes(group = .row))
% }
% pcp(mpg)
% pcp(mpg) + aes(colour = drv)
Hadley
I now have a decent section on that issue at the end of the
development of the polishing plots for publication chapter.
Unfortunately there are some things that it's currently basically
impossible to do with ggplot2 (like line up two plots with different
tick label lengths), so that descriptions of that will have to wait
until I've figured how to actually do it.
> 2) create a new object that you haven't implemented yet and use it in a
> plot. I'm thinking of a new grob such as a secondary x-axis for instance, or
> a new geom, ...
Again, I have a draft chapter on the topic, but at this point it's
very unlikely to make it into the book because the book is already
overdue for copyediting, and I probably need to make some
architectural changes before it's worth even beginning to describe how
to write new geoms. And implementing a secondary y axis isn't
something that's obvious to me how to do.
Maybe for the 2nd edition of the book ;)
Hadley