Extending ggplot functionality with ggproto - r

This solution addresses how to extend ggplot functionality using ggproto, specifically on a boxplot example. I wonder how this approach might be generalised.
For instance let's say I want to implement an algorithm to adjust the position of geom_point elements to reduce point overlapping (such as ggrepel does for labels). Grateful for a steer on how to approach this problem - i.e. how to access and edit the x/y values and point size parameters (for overlap identification). I'm assuming the solution is linked to ggproto, but if that's wrong I'd welcome advice.

Related

Why is there no col key for R's rgl?

I would like to draw $3$ dimensional scatter plots, or more precisely I have a program that gives me the mass distribution in the unit cube with respect to a 3 dimensional equidistant grid. You can interpret this as a continuous relaxation of a $3$ dimensional assignment problem if you want.
Anyway this is just to give you a very brief background since my actual problem is not really concerned with the maths behind the procedure but with the visualization. I have:
$n$ points in the unit cube $[0,1]^3$
each of the $n$ points is assigned a "weight" between $0$ and $\frac1n$ (typically a lot of the weights coincide, if there are too many different values, i use the cut command to reduce the range to, say $60$ different values)
And I'd like to plot the $n$ points in a color which corresponds to their weight.
Now I found the rgl Package in R which allows me to do exactly that and also provides a very nice interactive plot window but it doesn't seem to allow a "col key" parameter, i.e. I cannot add a continuous color legend to my plot.
On the other hand the package plot3D provides a function to do a $3$ dimensional scatterplot and easily allows me to add the col key. However plot3D does not work with interactive plots but merely gives me the option to specify the angle at which I want to look at the cube. In a $3$D setting I strongly prefer the interactive alternative.
Now is there a way to automatically add a continuous color legend to an rgl plot? If not, do you know why this hasn't been implemented? Or would you solve my problem completely different altogether?
P.S. sorry for the formatting, I'm new to SO and the math environment "$" doesn't seem to work here.
The reason this hasn't been implemented is because until fairly recently it wasn't easy to have a static legend and a dynamic plot in the same window.
Now it's easy; there's a legend3d() function that might do what you want, but I think you probably want a different sort of legend than it will draw. If you know how to draw what you want in 2D, you can use the bgplot3d() function to put it in the background of your plot.
Both of those options give bitmapped legends. It would also be possible to do vector-based legends, but that would be quite a bit more work.

Is it possible to create a pie in pie chart in SPSS or R?

I know it is possible to create such double pie charts in excel like this:
http://chandoo.org/wp/2009/12/02/group-small-slices-in-pie-charts/
but can SPSS or R do this also?
In relation to R:
The answer to the title question is "yes" ... see ?pie
As for the second question, the one in the body - it would be possible but would involve some coding. You'd have to draw two pie charts side by side (which could be managed with two calls to pie) and use segments or arrows (and text if necessary) to do the additional components of the plot.
Here's a rough example:
That required the fig argument of par to get them side-by-side.
(That example required a little fiddling to get right, but it would be possible to write a function to automate the details.)
The main issue I can see would be 'why on earth would you do it?' -- pie charts are a poor way of conveying information of this form. There are alternatives that result in much better ability to distinguish values, and less bias (such as what you get when comparing nearly horizontal vs nearly vertical slices).

Raster map vs alternative

I recently found this web page Crime in Downtown Houston that I'm interested in reproducing. This is my first learning experience with mapping in R and thus lack the vocabulary and understanding necessary to make appropriate decisions.
At the end of the page David Kahle states:
One last point might be helpful. In making these kinds of plots, one
might tempted to use the map raster file itself as a background. This
method can be used to make map plots much more quickly than the
methods described above. However, the method has one very significant
disadvantage which, if not handled properly, can destroy the entire
purpose of using the map.
In very plain English what is the difference between the raster file
approach and his approach?
Does the RgoogleMaps package have the ability to produce these types
of high quality maps as seen on the page I referenced above that
calls a google map into R?
I ask not because I lack information but the opposite. There's too much and I want to make a good decision(s) about the approach to pursue so I'm not wasting my time on outdated or inefficient techniques.
Feel free to pass along any readings you think would benefit me.
Thank you in advance for your direction.
Basically, you had two options at the time this plot was made:
draw the map as a layer using geom_tile, where each pixel of the image is mapped onto the x,y axes (slow but accurate)
add a background image to the plot, as a purely "cosmetic" annotation. This method is faster, because you can use grid.raster which draws images more efficiently, but the image is not constrained by the axes of the plotting region. In other words, you have to manually adjust the x and y axes limits to make sure that the image corresponds to the actual positions on the plot.
Now, I would suggest you look at the new annotation_raster in ggplot2 v. 0.9.0. It should have the advantage of speed and leaner output files, and still conform to the data space of the plot. I believe that this function, as well as geom_raster and annotation_map did not exist when David made those plots.

Extending ggplot2 properly?

Recently a few neat uses of ggplot2 have come up, and either partial or full solutions have been posted:
ggheat
Curly braces
position_dynamic
ggheat is notable because it rather breaks the ggplot metaphor by just plotting rather than returning an object.
The curly brace solutions are notable because none really fits in the ggplot2 high-level concept (e.g. you should be specifying a range of points you want to breaks, and then somewhere else be able to specify the geom of how you want that range displayed--brace, box, purple cow, etc.).
The ggplot2 book (which I will order soon and have read the 2 online chapters) seems to be about using the grammar and functions rather than writing new ones or extensively extending existing ones.
I would like to learn to add a specific feature or develop a new geom, and do it properly. ggplot2 may not be intended as a general graphics package in the same way that grid or base graphics are, but there are a great many graphs which are only a step or two extension from an existing ggplot2 geom. When these situations come up, I can typically put together enough objects to do something once, but what if I need the same plot a few dozen times? What if other people like it and want to use it--now they have to kludge through the same process each time they want that graph. It seems to me that the proper solution is to add in a stat_heatplot and geom_heatplot, or to add a geom_Tuftebox for Tufte box plots, etc. Yet I've never seen an example of actually extending ggplot2; just examples of how to use it.
What resources exist to dig deeper into ggplot2 and start extending it? I'm particularly interested in a high-level way to specify a range on an axis as described above, but general knowledge about what makes ggplot2 tick is welcome as well.
Absent a coherent guide (which rarely exists for sufficiently advanced tinkering and therefore may not exist here), how would one go about learning about the internals? Inspecting source is obviously one way, but what functions to start with, etc.
ggplot2 is gradually becoming more and more extensible. The development version, https://github.com/hadley/ggplot2/tree/develop, uses roxygen2 (instead of two separate homegrown systems), and has begun the switch from proto to simpler S3 classes (currently complete for coords and scales). These two changes should hopefully make the source code easier to understand, and hence easier for others to extend (backup by the fact that pull request for ggplot2 are increasing).
Another big improvement that will be included in the next version is Kohske Takahashi's improvements to the guide system (https://github.com/kohske/ggplot2/tree/feature/new-guides-with-gtable). As well as improving the default guides (e.g. with elegant continuous colour bars), his changes also make it easier to override the defaults with your own custom legends and axes. This would make it possible to draw the curly braces in the axes, where they probably belong.
The next big round of changes (which I probably won't be able to tackle until summer 2012) will include a rewrite of geoms, stats and position adjustments, along the lines of the sketch in the layers package (https://github.com/hadley/layers). This should make geoms, stats and position adjustments much easier to write, and will hopefully foster more community contributions, such as a geom_tufteboxplot.
I am not certain that I agree with your analysis. I'll explain why, and will then point you to some resources for writing your own geoms.
ggheat
As far as I can tell, ggheat returns an object of class ggplot. Thus it is a convenient wrapper around ggplot, customised for a specific use case. Although qplot is far more generic, it does in principle the same thing: It is a wrapper around ggplot that makes some informed guesses about the data and chooses sensible defaults. Hadley calls this plot functions and it is described briefly on page 181 of the ggplot2 book.
curly braces
The curly brace solution does exactly what the ggplot philosophy says, i.e. separate data from presentation. In this case, the data is generated by a little custom function and is stored in a data.frame. It is then displayed using a geom that makes sense, i.e. geom_line.
quo vadis?
You have noted (in the r chat room) that you would prefer to have a more generic approach to plotting the curly braces. Something along the following lines (and I paraphrase and extend at the same time):
Supply data in the form of a bounding box coordinates (i.e. x0, x1, y0 and y1)
Specify a "statistic", such as brace, box or whatever
Specify a geom, such as geom_custom_shape
This sounds like a nice generalisation and extension of the ideas behind the curly brace solution, and would clearly require writing a new geom. There is an official ggplot wiki, where you can find instructions for creating a new geom.
Why do you want to extend it? What is the motivation? As I see it ggplot2 is meant to be a high-level graphics package designed to produce nice figures from a particular data set. And do things right and make other things easy: like scales, legends etc. ggplot2 is not meant to be a general-purpose graphics tool-kit. Like lattice it has a particular paradigm in mind and you use it for that purpose.
grid is the underlying graphical toolkit you want to use to do general purpose, customised plotting. And IIRC, it is relatively easy to add grid grobs to lattice or ggplot2 plots/objects, for this sort of arbitrary notation/annotation etc.
What doesn't make too much sense is extending ggplot2 or lattice along the lines you are thinking. I don't see why the ggplot2 can't do heatplots as it is? Or am I missing something here?
What would be very useful would be if the data processing guts of ggplot2 or lattice were available for others to write actual plotting code on top of. Hadley has mentioned this somewhere before.
ggplot2, in particular, and lattice are quite difficult codes to get into to read/understand. ggplot2 uses the proto package for a version of OOP, which means you need to understand what that is doing as well as ggplot2 semantics. lattice is similar as there is a lot of computing on the language done there that, if you are not familiar with that sort of R programming, can by quite intimidating, daunting and impenetrable!
For grid, I suggest you look at Paul Murrell's R Graphics book, a second edition of which is with the publisher: http://www.stat.auckland.ac.nz/~paul/RG2e/
Edit: The point I was intending to get across was that the interfaces provided by packages like ggplot2 and lattice are necessarily high-level. Extending them is fine as long as they stick to the paradigm/philosophy in use. Heatplots can already be made by using existing geoms; part of the philosophy of the ggplot system is to separate the data from the display/presentation, and to use geoms in interesting ways to produce the desired display.
Wrapping base ggplot + geom calls into a more user friendly function is OK as long as i) it works like ggplot already does and returns an object, and ii) it doesn't have an interface that is too different from the way ggplot works. Developers are free to write whatever code they want, it just isn't helpful to the wider community to provide wrappers that move too far away from the original's workings. That leads to confusion on the part of the user and doesn't foster learning of ggplot2 itself.
The dynamic positioning idea is interesting; you could include these ideas in all plotting packages. You could bolt this into a geom, or alternatively as an external function that modified the input coordinates to produce a new data object that could be used by the relevant geom. That same function could be used for other plotting packages - it wouldn't need to be ggplot-specific.

How to avoid overplotting (for points) using base-graph?

I am in my way of finishing the graphs for a paper and decided (after a discussion on stats.stackoverflow), in order to transmit as much information as possible, to create the following graph that present both in the foreground the means and in the background the raw data:
However, one problem remains and that is overplotting. For example, the marked point looks like it reflects one data point, but in fact 5 data points exists with the same value at that place.
Therefore, I would like to know if there is a way to deal with overplotting in base graph using points as the function.
It would be ideal if e.g., the respective points get darker, or thicker or,...
Manually doing it is not an option (too many graphs and points like this). Furthermore, ggplot2 is also not what I want to learn to deal with this single problem (one reason is that I tend to like dual-axes what is not supprted in ggplot2).
Update: I wrote a function which automatically creates the above graphs and avoids overplotting by adding vertical or horizontal jitter (or both): check it out!
This function is now available as raw.means.plot and raw.means.plot2 in the plotrix package (on CRAN).
Standard approach is to add some noise to the data before plotting. R has a function jitter() which does exactly that. You could use it to add the necessary noise to the coordinates in your plot. eg:
X <- rep(1:10,10)
Z <- as.factor(sample(letters[1:10],100,replace=T))
plot(jitter(as.numeric(Z),factor=0.2),X,xaxt="n")
axis(1,at=1:10,labels=levels(Z))
Besides jittering, another good approach is alpha blending which you can obtain (on the graphics devices supporing it) as the fourth color parameter. I provided an example for 'overplotting' of two histograms in this SO question.
One additional idea for the general problem of showing the number of points is using a rug plot (rug function), this places small tick marks along the margin that can show how many points contribute (still use jittering or alpha blending for ties). This allows the actual points to show their true rather than jittered values, but the rug can then indicate which parts of the plot have more values.
For the example plot direct jittering or alpha blending is probably best, but in some other cases the rug plot can be useful.
You may also use sunflowerplot, while it would be hard to implement it here. I would use alpha-blending, as Dirk suggested.

Resources