Passing a continuous fill variable to geom_dotplot

777 views
Skip to first unread message

Tom W

unread,
Mar 16, 2012, 11:45:18 PM3/16/12
to ggp...@googlegroups.com
I've been really enjoying the new geoms in 0.9. I've hit an unexpected barrier with geom_dotplot.


d2 <- data.frame(v1 = runif(10, 1, 40),
                 v2 = runif(10, 0,1))

ggplot(d2, aes(x = v1, fill = v2)) + geom_dotplot()

provides the following error message

stat_bindot: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
Error in xyz %*% solve(M) : non-conformable arguments

Removing the fill option provides the plot with no errors.

Am I missing something?

Tom

Jean-Olivier Irisson

unread,
Mar 17, 2012, 9:16:38 AM3/17/12
to Tom W, ggp...@googlegroups.com

I've had this error quite often also, without being able to track it down. I can say that it's not related to geom_dotplot or stat_bin (which is what emits the first message). I got it with colour of points on a scatter plot and on fill of tiles on a tile plot.

Any insight is welcome.

Jean-Olivier Irisson
---
Observatoire Océanologique
Station Zoologique, B.P. 28, Chemin du Lazaret
06230 Villefranche-sur-Mer
Tel: +33 04 93 76 38 04
Mob: +33 06 21 05 19 90
http://jo.irisson.com/

Winston Chang

unread,
Mar 17, 2012, 10:21:57 AM3/17/12
to Jean-Olivier Irisson, Tom W, ggp...@googlegroups.com
I can't explain offhand the details of why it gives that error, but I can say that the way geom_dotplot is written, it _shouldn't_ work with a continuous fill.

It uses stat_bindot, which is similar to stat_bin -- essentially, it gets an input data frame, and then returns a data frame with an x value for each bin, and a count of the number of dots in the bin. The individual data points aren't in the new data frame; the new data frame only has counts. Then the geom_dotplot draws a stack of n dots for each bin. In other words, instead of "moving" the data points into each bin, it simply gets a count of the number of cases in each bin.

You get the same error if you try to use geom_histogram, which uses stat_bin.

d2 <- data.frame(v1 = runif(10, 1, 40),
                 v2 = runif(10, 0,1))

ggplot(d2, aes(x = v1, fill = v2)) + geom_dotplot()
# stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
# Error in xyz %*% solve(M) : non-conformable arguments

ggplot(d2, aes(x = v1, fill = v2)) + geom_histogram()
# stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
# Error in xyz %*% solve(M) : non-conformable arguments

-Winston


--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: http://gist.github.com/270442

To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

Tom W

unread,
Mar 17, 2012, 2:47:31 PM3/17/12
to ggp...@googlegroups.com, Jean-Olivier Irisson, Tom W
hi Winston--thanks for such an authoritative answer. I appreciate if there's a fundamental technical obstacle to implementing this option.

I also think it would occasionally be useful to have this capability--I'm not sure that it would contradict the underlying grammar. But anyway, thanks so much for the work you've done implementing this new facility--the new features in 0.9 have been tremendous.

Tom
-Winston

Winston Chang

unread,
Mar 17, 2012, 3:59:55 PM3/17/12
to Tom W, ggp...@googlegroups.com, Jean-Olivier Irisson
I'm glad you find it useful!
It occurred to me that it's possible to simulate what you're looking for if you're willing to have a discretized scale. (I think it's also perceptually easier to map colors back to numerical values using a discrete scale.) This requires a development branch of ggplot2 from github, where I added the ability to use stacking with dot plots.

library(devtools)
install_github('ggplot2', 'wch', 'dotplot-stack')
library(ggplot2)

set.seed(12)
d2 <- data.frame(v1 = runif(40, 1, 40),
                 v2 = runif(40, 0, 1))

# Convert the continuous values to discrete
d2$v3 <- cut(d2$v2, seq(0, 1, 0.2))

# Bin positions determined by data (dot-density)
ggplot(d2, aes(x = v1, fill = v3)) +
  geom_dotplot(stackgroups=TRUE, binpositions="all") +
  scale_fill_brewer()

# Regularly-spaced bins
ggplot(d2, aes(x = v1, fill = v3)) +
  geom_dotplot(stackgroups=TRUE, method="histodot") +
  scale_fill_brewer()

Make sure you have the latest devtools because there was a version that had problems installing branches from github.

I'm not sure if building in the capability to use a continuous fill would necessarily violate the grammar... I think it would require a complete reworking of the way stat_bindot works, and how geom_dotplot deals with the binned data. There's also the issue of how to vertically order the dots based on a continuous variable. I can't think of another case where something like this is done, so it would probably have to be a special case written into geom_dotplot. Overall, it probably makes more sense to just use the discrete method with stacking. Hopefully stacking will be in ggplot2 0.9.1.

-Winston

dot-1.png
dot-2.png

Winston Chang

unread,
Mar 17, 2012, 4:05:11 PM3/17/12
to Tom W, ggp...@googlegroups.com, Jean-Olivier Irisson
I forgot to mention that you should probably do dev_mode() right after loading devtools, so that you don't mess up your regular installation of ggplot2:
  library(devtools)
  dev_mode()

Tom W

unread,
Mar 17, 2012, 4:59:49 PM3/17/12
to ggp...@googlegroups.com, Tom W, Jean-Olivier Irisson
wow, thanks! I'll try that our right away.

we users of open source software have no right to expect such responsiveness from volunteer programmers!
Reply all
Reply to author
Forward
0 new messages