From maechler at stat.math.ethz.ch  Fri Nov 14 19:24:05 2003
From: maechler at stat.math.ethz.ch (maechler@stat.math.ethz.ch)
Date: Fri Nov 14 19:24:08 2003
Subject: [Rd] wishlist item: changing origin of plot (PR#5045)
Message-ID: <20031114182405.EDBAFEFB8@slim.kubism.ku.dk>

>>>>> "Paul" == Paul Murrell <p.murrell@auckland.ac.nz>
>>>>>     on Fri, 14 Nov 2003 09:21:12 +1300 writes:

    Paul> Hi
    Paul> Duncan Murdoch wrote:
    >> On Wed, 12 Nov 2003 10:24:28 +0100 (CET), you wrote:
    >> 
    >> 
    >>> Do you think it would be worth adding options to plot commands to
    >>> reverse axes?
    >>> 
    >>> Here is a simple example:
    >>> 
    >>> 
    >>>> x <- 1:12
    >>>> plot(x)
    >>> 
    >>> 
    >>> Whereas if I want the x-axis reversed, I need to know the range of
    >>> the x data points:
    >>> 
    >>> 
    >>>> plot(x, xlim=c(12,1))
    >>> 
    >> 
    >> This seems like a fairly obscure need, and it can be done by
    >> calculating the range of x at plot time, e.g.
    >> 
    >> plot(x, y, xlim=rev(range(x)))
    >> 
    >> or
    >> 
    >> plot(y, xlim=c(length(y),1))


    Paul> That assumes that you know how the axis range is going
    Paul> to be calculated.  If a plotting function (barplot
    Paul> springs to mind) calculates the axis range internally
    Paul> then the user has a hard task to try and emulate that
    Paul> behaviour (in order to rev() it).  OTOH, the same
    Paul> point raises the potential problem that LOTS of
    Paul> plotting functions would possibly have to be updated
    Paul> because they assume that the x-scale goes
    Paul> left-to-right (here interaction.plot springs to mind
    Paul> because it allocates space within the plot for a
    Paul> legend).

    Paul> Paul

    >> I'd be happier with including one of those in the example code rather
    >> than with adding another couple of parameters to par.
    >> 
    >> Duncan Murdoch

StephenE> So, maybe something like:
StephenE>  
StephenE> plot(x, x.rev=TRUE)
StephenE>  
StephenE> could be implemented.  X.REV could default to FALSE, and then 
StephenE> plot.default could have something like:
StephenE>  
StephenE>  xlim <- if (is.null(xlim)) {
StephenE>  	if (x.rev)
StephenE>  		rev( range(xy$x[is.finite(xy$x)]))
StephenE>  	else 
StephenE>  	        range(xy$x[is.finite(xy$x)])
StephenE>  }
StephenE>  
StephenE> So, it would reverse the xlimits only if xlim was not specified.
StephenE> Likewise, code could be added for ylim.

A much simpler alternative (and more in line with Stephen's
original whish ?!) is to only make this a new argument
for plot.default();  no par()'s at all.

This would make the argument work correctly for quite a few plot
methods that pass their "..." to plot.default(), but might not
be clean enough, since some things won't work {as e.g. Paul has mentioned}.

Martin


[Rd] wishlist item: changing origin of plot (PR#5045)
maechler@stat.math.ethz.ch