Search code examples
rlattice

How to define pch and color based on columns in lattice plot


I am making a lattice plot and I would like to use the value in one column to define the pch and another column to define color of points. Something like:

xyplot(mpg ~ wt | cyl,
       data=mtcars,
       col = gear,
       pch = carb)

There are unique pch points in the second and third panels, but these points are only unique within the plots, not among all the plots (as they should be). You can see this if you use the following code:

xyplot(mpg ~ wt | cyl, 
       data=mtcars, 
       groups = carb
)

This plot looks great for one group, but if you try to invoke two groups it simply takes unique combinations of those two variables and plots them as unique colors.

The issue causing problems with this solution and the one provided as an answer below is that not every value for each group is present in each panel, and they are almost never in the same order. My actual data file is very large, and it's not possible to sort my way out of this mess. It would be best if I could just use the value in a column to actually define a color or pch for an entire plot, not just each panel. R is just assuming the order of new values in each panel should define a change in pch or color.


Solution

  • A small edit to the answer given by @LocoGris.

    xyplot(mpg ~ wt | cyl,
              panel = function(x, y, ..., groups, subscripts) {
                  pch <- mypch[factor(carb)[subscripts]]
                  col <- mycol[factor(gear)[subscripts]]
                  grp <- c(gear,carb)
                  panel.xyplot(x, y, pch = pch, col = col)
              }
    )
    

    This is apparantly an actual solution, and it is robust to sorting the data frame. This answer was provided by a user on another forum. Thank you, Peter Langfelder!

    Here is another solution thanks to the r-help email list:

    xyplot(mpg ~wt|cyl, data = mtcars,
          col = mtcars$gear,
          pch = mtcars$carb,
          panel = function(x,y, subscripts, col, pch,...)
          {
             panel.xyplot(x,y, col = col[subscripts], pch = pch[subscripts] )
          }
    )
    

    Thanks to Bert Gunter for that one!