[Rd] boxplot() confuses x- and y-axes (PR#10345)
marc_schwartz at comcast.net
marc_schwartz at comcast.net
Mon Oct 15 21:05:18 CEST 2007
--=-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 at 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--
More information about the R-devel
mailing list