Re: [Rd] boxplot() confuses x- and y-axes (PR#10345)

From: <marc_schwartz_at_comcast.net>
Date: Mon, 15 Oct 2007 21:05:18 +0200 (CEST)

--=-ZyOtZFb05MaZLi4/Ovwu
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On Mon, 2007-10-15 at 18:25 +0200, maechler_at_stat.math.ethz.ch wrote:
> >>>>> "JO" == Jari Oksanen <jarioksa@sun3.oulu.fi>
> >>>>> on Mon, 15 Oct 2007 16:42:24 +0300 writes:
>
> JO> On Mon, 2007-10-15 at 15:25 +0200, maechler_at_stat.math.ethz.ch wrote:
> >> >>>>> "ms" == marc schwartz <marc_schwartz_at_comcast.net>
> >> >>>>> on Mon, 15 Oct 2007 14:20:16 +0200 (CEST) writes:
> >>
> ms> On Mon, 2007-10-15 at 10:30 +0200, bob.ohara_at_helsinki.fi wrote:
> >> >> Full_Name: Bob O'Hara
> >> >> Version: 2.6.0
> >> >> OS: Windows XP
> >> >> Submission from: (NULL) (88.112.20.250)
> >> >>
> >> >>
> >> >> Using horizontal=TRUE with boxplot() confuses it as to what is an x- or y-axis.
> >> >> At least, xlim= and ylim= are the wrong way round, log="x" (or "y") and xaxt=
> >> >> work as expected, I haven't looked at anything else.
> >> >>
> >> >> Some code to see if you can reproduce the bug (or discover it's in my head...):
> >> >>
> >> >> boxplot(count ~ spray, data = InsectSprays)
> >> >>
> >> >> # Try to change x-axis:
> >> >> boxplot(count ~ spray, data = InsectSprays, xlim=c(0,50))
> >> >>
> >> >> # Plot horizontally:
> >> >> boxplot(count ~ spray, data = InsectSprays, horizontal=TRUE)
> >> >>
> >> >> # Now try to change x-axis:
> >> >> boxplot(count ~ spray, data = InsectSprays, horizontal=TRUE, xlim=c(0,50))
> >> >> # Changes y-axis!
> >> >>
> >> >> # Now try to change y-axis:
> >> >> boxplot(count ~ spray, data = InsectSprays, horizontal=TRUE, ylim=c(0,50))
> >> >> # Changes x-axis!
> >> >>
> >> >> # Plot x-axis on log scale:
> >> >> boxplot(count+1 ~ spray, data = InsectSprays, horizontal=TRUE, log="x")
> >> >> # Does indeed change x-axis
> >> >>
> >> >> # Don't add ticks on x-axis:
> >> >> boxplot(count ~ spray, data = InsectSprays, horizontal=TRUE, xaxt="n")
> >> >> # Works as expected.
> >>
> ms> Hi Bob,
> >>
> ms> No, it's not in your head. This is documented in ?bxp, which is the
> ms> function that actually does the plotting for boxplot(). See the
> ms> description of 'pars' in ?bxp:
> >>
> ms> "Currently, yaxs and ylim are used €‹‚“along the boxplot€„¢, i.e.,
> ms> vertically, when horizontal is false, and xlim horizontally."
> >>
> ms> So essentially, the named 'x' and 'y' axes are rotated 90 degrees when
> ms> you use 'horizontal = TRUE', rather than the vertical axis always being
> ms> 'y' and the horizontal axis always being 'x'. This has been discussed on
> ms> the lists previously.
> >>
> >> Yes; thank you, Marc.
> >>
> >> And the reason for this is very sensible I think:
> >>
> >> If you have a longish boxplot() or bxp() command,
> >> and you just want to go from vertical to horizontal or vice
> >> versa, it makes most sense just to have to change the
> >> 'horizontal' flag and not having to see if there are other 'x*'
> >> and or 'y*' arguments that all need to be changed as well.
> >>
> JO> Except that you must change xaxt/yaxt and log="x"/log="y" which do not
> JO> follow the "along the box" logic, and behave differently than
> JO> xlim/ylim.
>
> JO> Nothing of this is fatal, but this probably needs more than one
> JO> iteration to find which way each of the x* and y* arguments works.
>
> Oops!! Thank you Jari, for the note.
>
> What you describe is then very unfortunate, and I hadn't been
> aware of that.
>
> ``of course'', making any change to consistency
> would break existing code that consciously works with the
> current mis-"designed" behavior.
>
> But now I understand why we have the word "currently"
> in the description mentioned above.
>
> So given the help file, we should consider dropping the whole
> ``along the boxplot'' idea?
>
> {{well, yes, we should drop "traditional graphics" and work with
> grid-based graphical objects ("grob"s) that can be drawn
> vertically or horizontally,
> e.g., in lattice or (most probably) ggplot2
> }}
>
> Martin

The key code in question, from boxplot.R, seems to be:

    if (!add) {

	plot.new()
	## shall we switch log for horizontal with
	## switch(log, x="y", y="x", log) ??
	if (horizontal)
	    plot.window(ylim = xlim, xlim = ylim, log = log, xaxs = pars$yaxs)
	else
	    plot.window(xlim = xlim, ylim = ylim, log = log, yaxs = pars$yaxs)
    }
    xlog <- (par("ylog") && horizontal) || (par("xlog") && !horizontal)

So it would appear that ylim/xlim and xaxs/yaxs are interchanged when horizontal = TRUE. All? other axis specific pars remain as per normal.

I have attached a proposed patch against bxp.Rd (against the current svn copy) for consideration. Hopefully this makes ?bxp a bit more clear.

If any changes are to be made to current behavior, it would be good to do this incrementally, with a note/warning added to 2.7.1 and then changed in 2.8.0. If that is too soon, then increment by one version.

Thanks all,

Marc

--=-ZyOtZFb05MaZLi4/Ovwu

Content-Disposition: attachment; filename=diff.patch
Content-Type: text/x-patch; name=diff.patch; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

--- bxp.Rd	2007-10-15 13:27:21.000000000 -0500
+++ bxp.Rd.patch	2007-10-15 13:55:42.000000000 -0500
@@ -43,8 +43,8 @@

   \item{frame.plot}{logical, indicating if a \sQuote{frame}

     (\code{\link{box}}) should be drawn; defaults to \code{TRUE}, unless
     \code{axes = FALSE} is specified.}

- \item{horizontal}{logical indicating if the boxplots should be - horizontal; default \code{FALSE} means vertical boxes.} + \item{horizontal}{logical indicating if the boxplots should be + horizontal; default \code{FALSE} means vertical boxes. See note.}

   \item{add}{logical, if true \emph{add} boxplot to current plot.}    \item{at}{numeric vector giving the locations where the boxplots      should be drawn, particularly when \code{add = TRUE}; defaults to @@ -56,9 +56,6 @@

     normally(\code{\dots}), see the following.  (Those in \code{\dots}
     take precedence over those in \code{pars}.)
 
-    Currently, \code{yaxs} and \code{ylim} are used \sQuote{along the
-      boxplot}, i.e., vertically, when \code{horizontal} is
-    false, and \code{xlim} horizontally.
     \code{xaxt}, \code{yaxt}, \code{las}, \code{cex.axis}, and
     \code{col.axis} are passed to \code{\link{axis}}, and \code{main},
     \code{cex.main}, \code{col.main}, \code{sub}, \code{cex.sub},
@@ -101,10 +98,15 @@

   }%.../pars
 }
 \note{
- if \code{add = FALSE}, the default is \code{xlim = c(0.5, n +0.5)}. + If \code{add = FALSE}, the default is \code{xlim = c(0.5, n +0.5)}.

   It will usually be a good idea to specify the latter if the "x" axis    has a log scale or \code{at} is specified or \code{width} is far from    uniform.

+
+  If \code{horizontal = TRUE}, the "y" axis is the horizontal axis and the "x"
+  axis is the vertical axis. Graphical pars \code{xlim/ylim} and 
+  \code{xaxs/yaxs} are reversed in this case. Other axis related pars treat
+  the vertical axis as "y" and the horizontal axis as "x".
 }
 \value{
   An invisible vector, actually identical to the \code{at} argument,

--=-ZyOtZFb05MaZLi4/Ovwu--



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Mon 15 Oct 2007 - 19:13:32 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 25 Oct 2007 - 11:37:11 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.