2

I am trying to make a scatter plot in R using these points:

"Cleveland points

(as far as I can trace, W. Cleveland suggested using these for sparse and dense, respectively, scatter plots -- I now call them "Cleveland points".)

The bottom row should be straightforward, and the top row could be achieved by doing some smart overplotting (i.e. plotting two symbols on top of each other). But this will not suffice when plotting the legend.

As a solution I was therefore imagining getting a font that contains these 10 symbols and instruct R to use this font when plotting the points + legend. (And now it occurs to me, that I might just use text with the custom font to plot the points. But this does not solve the legend issue.)

I have also considered using ggplot2, but this would perhaps easiest be implemented via a scale?

Question: Any suggestions on how to use these symbols (preferable the top row), that can also be used in the legend?

MrGumble
  • 5,631
  • 1
  • 18
  • 33
  • 5
    Try using them via Unicode? http://stackoverflow.com/questions/5886018/using-unicode-dingbat-like-glyphs-in-r-graphics-across-devices-platforms-e – Ben Bolker Sep 09 '13 at 12:12

1 Answers1

1

Here is one approach using base graphics and the my.symbols function from the TeachingDemos package:

library(TeachingDemos)
ms.Cleveland <- function(num.pt = 1, cex=2, ...) {
    funs <- list(
        open = function(cex, ...) 
            points(0,0, pch=1, lwd=2, cex=cex, ...),
        filled = function(cex, ...)
            points(0,0, pch=16, cex=cex, ...),
        half = function(cex, ...)
            points(0,0, pch=1, lwd=5, cex=cex, ...),
        vert = function(cex, ...) {
            points(0,0, pch=1, lwd=2, cex=cex, ...)
            points(0,0, pch='|', lwd=2, cex=cex/2, ...)
          },
        dot = function(....) {
            points(0,0, pch=1, lwd=2, cex=cex, ...)
            points(0,0, pch=16, cex=cex/3, ...)
          }
    )
    funs[[num.pt]](cex, ...)
}

### create size variable for mtcars
sz <- findInterval( mtcars$wt, quantile( mtcars$wt, c(0.2, 0.4, 0.6, 0.8) ) ) + 1

with(mtcars, my.symbols(wt, mpg, ms.Cleveland, num.pt=sz, add=FALSE, 
    symb.plots=TRUE))
tmp <- legend('topright', pch=1, col=NA, pt.cex=2,
    legend=c('Small', 'SMed', 'Medium', 'LMed', 'Large'))

my.symbols( (tmp$rect$left + tmp$text$x)/2, tmp$text$y, ms.Cleveland, num.pt=1:5,
    symb.plots=TRUE)

The ms.Cleveland function plots the points according to a number (1 to 5) or name and uses overplotting for the last 2 points (may want to tweak the functions a bit).

Then the legend is drawn using the regular legend function, but with col=NA there is place for the symbols, but they are not drawn. Then my.symbols is used again to place the symbols within the legend at the point halfway between the left edge of the box and the start of the text.

Greg Snow
  • 48,497
  • 6
  • 83
  • 110