Re: Why does the number of aesthetics need to be constant across geoms and other changes?

5,154 views
Skip to first unread message

Dennis Murphy

unread,
Jun 26, 2012, 11:41:24 AM6/26/12
to Brian Weaver, ggp...@googlegroups.com
Hi:

On Tue, Jun 26, 2012 at 7:46 AM, Brian Weaver <the...@alumni.iastate.edu> wrote:
> Hello ggplot2 group:
>
> I am a long time user of ggplot2 and am trying to convert my whole stats
> group to using this awesome package (not an easy task when I work with
> people who are from the old Bell labs which is the birthplace of
> lattice/trellis, but this is besides the point).
>
> I recently updated my ggplot2 package to 0.9.1 (I think this is the most
> current, it at least matches the version in the repository) and I feel that
> this version is more difficult to work with.  Here is an example of what I
> mean.
>
> Consider the simple example:
>
> dat <- data.frame(time = 1:10, obs = 2*(1:10), group = factor(c(rep(1,5),
> rep(2,5) ) ) )
>
> p <- ggplot(data = dat,aes(x = time, y = obs, colour = group)) +
> geom_point()
>
> Now in the older versions of ggplot2, if I wanted to add a line that
> connects two points, all I had to do was:
>
> p + geom_line(aes(x = c(5,8), y = c(10,5) ) )
>
> but I get the following error:
>
> Error: Aesthetics must either be length one, or the same length as the
> dataProblems:c(5, 8), c(10, 5)
>
> So now in order to get the plot with an added line, I have to add the
> additional aesthetic:
>
> p + geom_line(aes(x = c(5,8), y = c(10,5) ), colour = 'black' )
>
> or
>
> p + geom_line(aes(x = c(5,8), y = c(10,5), colour = 'black') )
>
> Is this a bug, is there a reason to add this additional level complexity
> that I currently do not understand (and please explain if so), or is there a
> better fix that is better than mine that makes things easier and clearer.

No, because you defined colour as an aesthetic in the ggplot() call,
so ggplot2 expects a colour aesthetic in *all* subsequent layers. To
avoid it, take colour out of ggplot() and move it to geom_point(), as
in

ggplot(data = dat, aes(x = time, y = obs)) +
geom_point(aes(colour = group)) +
geom_line(aes(x = c(5, 8), y = c(10, 5)))

Aside: it's probably a little cleaner to do the following:

dat2 <- data.frame(time = c(5, 8), obs = c(10, 5))
p <- ggplot(data = dat, aes(x = time, y = obs)) +
geom_point(aes(colour = group))
p + geom_line(data = dat2)

This behavior is not new to 0.9.x; it's been around for a while.
>
> I am also finding this harder to build a plot layer by layer, especially if
> I want to add additional information that may not necessarily have the same
> structure as the current data frame that ggplot saves in its object.
>  Meaning if I have one data frame (say data1) with columns "w" and "x" and
> create a ggplot object with this data frame, it is no longer easy to add a
> new data frame (say data2) with columns "y" and "z" unless I change their
> names to "w" and "x" (unless I am doing something wrong).  In earlier
> versions I could just do:
>
> data1 <- data.frame(w = 1:5, x = 1:5)
>
> data2 <- data.frame(y = 6:10, z = 6:10)
>
> ggplot(data = data1, aes(x = w, y = x)) + geom_point() + geom_point(data =
> data2,aes(x = y, y = z))
>
> But now I get the error (which I think arises because it is looking for z in
> the data frame data1):
>
> Error in eval(expr, envir, enclos) : object 'z' not found

Works for me on 0.9.1; AFAICT, you coded it correctly.

> sessionInfo()
R version 2.15.1 (2012-06-22)
Platform: x86_64-pc-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] reshape2_1.2.1 plyr_1.7.1 ggplot2_0.9.1

loaded via a namespace (and not attached):
[1] colorspace_1.1-1 dichromat_1.2-4 digest_0.5.2 grid_2.15.1
[5] labeling_0.1 MASS_7.3-18 memoise_0.1 munsell_0.3
[9] proto_0.3-9.2 RColorBrewer_1.0-5 scales_0.2.1 stringr_0.6

Dennis

>
> In earlier versions this was not the case and it was very easy to
> incorporate two different data sets using the above code.  Instead now I
> have to use the following fix (which I am not a fan of because it involves
> changing column names):
>
> colnames(data2) <- c('w', 'x')
>
> ggplot(mapping = aes(x = w, y = x)) + geom_point(data = data1) +
> geom_point(data = data2)
>
> For what it is worth, I am finding this much more difficult to work with
> especially since I have been using ggplot2 for a while and I all my code
> that I created in earlier versions is no longer compatible with the current
> version.
>
> Sorry if I am sounding critical, this is not my intention. I am just trying
> to understand this new requirement.
>
> Thanks and I look forward to your responses,
>
> Brian
>
> --
> 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

Joran

unread,
Jun 26, 2012, 12:10:39 PM6/26/12
to ggp...@googlegroups.com, Brian Weaver
Oddly, all of those examples ran fine for me, unaltered. (R 2.15.1, ggplot2 0.9.1). I was actually half expecting the first one to fail because of the color aesthetic issue Dennis described. I think that may have to do with which aesthetics are required for each geom, but I could be wrong. (i.e. color isn't a required aesthetic for geom_line)
> To unsubscribe: email ggplot2+unsubscribe@googlegroups.com
> More options: http://groups.google.com/group/ggplot2

Brian Weaver

unread,
Jun 26, 2012, 12:22:50 PM6/26/12
to Dennis Murphy, ggp...@googlegroups.com
Thanks Dennis:

ok I will take your suggestion.  The specific example that motivated my first bit of code was using geom_contour.  Very loosely, the code was (this is not meant to be reproducible as my simpler example earlier roughly captures this):

p <- ggplot(dat,aes(x = n, y = m, z = cost)) + geom_contour()

p + geom_line(aes(x = c(1,2), y = c(3,4) ) )

and this used to work fine but no longer does.  But using your suggestion, I have changed this to:

p <- ggplot(dat,aes(x = n, y = m)) + geom_contour(dat, aes(z = cost) )

p + geom_line(aes(x = c(1,2), y = c(3,4) ) )

I do prefer the first approach over this fix since first I created the contour plot, which is natural (at least initially) to include all three aesthetics (x, y, z) in the initial ggplot object and then add the line geometric objects (which serve as annotations later on).  It feels less natural to always exclude the z variable in the ggplot object when I want to make a contour plot (of course this is just my opinion).

For the second example I originally posted, embarrassingly I updated R to 15.x (I was running 14.x) and it is working fine now :/ (though the first still didn't).      

Thanks for your help.

Brian

P.S.  Here is the sysinfo:

sessionInfo()

R version 2.15.1 (2012-06-22)

Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)


locale:

[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8


attached base packages:

[1] stats     graphics  grDevices utils     datasets  methods   base     


other attached packages:

[1] ggplot2_0.9.1


loaded via a namespace (and not attached):

 [1] colorspace_1.1-1   dichromat_1.2-4    digest_0.5.2       grid_2.15.1        labeling_0.1       MASS_7.3-18        memoise_0.1        munsell_0.3        plyr_1.7.1        

[10] proto_0.3-9.2      RColorBrewer_1.0-5 reshape2_1.2.1     scales_0.2.1       stringr_0.6        tools_2.15.1

Reply all
Reply to author
Forward
0 new messages