Search code examples
rdata-visualizationlattice

Lattice's `panel.rug` produces different line length with wide plot


When producing a wide plot in lattice with margins that include panel.rug(), the length of the lines in rugged margins is longer in the y-axis than x-axis:

library(lattice)
png(width=800, height=400)
xyplot(Fertility ~ Education, swiss, panel = function(x, y,...) {
  panel.xyplot(x, y, col=1, pch=16)
  panel.rug(x, y, col=1, end= ...)})
dev.off()

enter image description here

I would like those rug lines in x- and y-axes to be the same length regardless of the shape of a plot (note: right now the rug lines will only be the same length when the plot is square).


Solution

  • With lattice, just change the coordinate system used by panel.rug from its default ("npc") to "snpc":

    library(lattice)
    
    ## png(width=800, height=400)
    xyplot(Fertility ~ Education, swiss, panel = function(x, y,...) {
      panel.xyplot(x, y, col=1, pch=16)
      panel.rug(x = x, y = y,  
                x.units = rep("snpc", 2),  y.units = rep("snpc", 2), 
                col=1, end= ...)
    })
    ## dev.off()
    

    enter image description here

    To see why this gets you what you want, refer to ?unit for its description of what those two coordinate systems mean:

     Possible ‘units’ (coordinate systems) are:
    
     ‘"npc"’ Normalised Parent Coordinates (the default).  The origin
          of the viewport is (0, 0) and the viewport has a width and
          height of 1 unit.  For example, (0.5, 0.5) is the centre of
          the viewport.
    
     ‘"snpc"’ Square Normalised Parent Coordinates.  Same as Normalised
          Parent Coordinates, except gives the same answer for
          horizontal and vertical locations/dimensions.  It uses the
          _lesser_ of npc-width and npc-height.  This is useful for
          making things which are a proportion of the viewport, but
          have to be square (or have a fixed aspect ratio).