Skip to content

plot() axis problem

11 messages · Paul Murrell, Jim Lemon, Peter Dalgaard +3 more

#
This posting just illustrates the problem with plot()

x<-1:20
y<-c(1:10,301:310)
plot(x,y)
xrange<-c(1,10)
plot(x,y,xlim=xrange) #uses ylim=range(y)
This is the default behaviour of plot() and I think it is not sensible.
By default the range of the y axis should span the y values corresponding
to the points plotted. In this example the yaxis should span 1-10 rather
than 1-310. This does the sensible thing:

plot(x,y,xlim=xrange,ylim=range(y[x<=max(xrange) & x>=min(xrange)]))

I suggest that plot() changes to this default behaviour.

Bill

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
2 days later
#
Hi
The only objections I can think of so far concern (backward) compatibility:
(i) R currently does what S-Plus does -- that helps portability of S code
(ii) If we made this change then users' existing R code might start behaving
differently

The second problem is a fairly significant one I think -- it is impossible
to check for all instances and the change would be potentially quite
dramatic.  Perhaps you could argue that it would be sufficiently rare ...?

Any other arguments for or against?

Paul


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Paul Murrell wrote:
It depends upon how you interpret the request to plot().  

1) Plot the first 10 values of each of two 20 element numeric vectors
against each other (i.e. plot(x[1:10],y[1:10])) and the result is
probably what is wanted.

2) Plot two 20 element numeric vectors against each other, but limit the
range of the plot on one set of values (i.e. plot(x,y,xlim=c(1,10))) -
which plot() does, but without calculating the revised range for the
values that will be _visible_.

The example uses a rather artificial dataset, neatly divided into
monotonically increasing low and high values.  Any permutation of those
values that did not fall into that pattern would render the question
meaningless.  For example, try

y<-c(1,301,2,3,4,5,6,7,8,9,10,302:310)
plot(x,y,xlim=c(1,10))

If the range condition is to be applied, perhaps it should be as:

plot(x[x>=1 & x<=10],y[x>=1 & x<=10])

I think the present behavior of plot() is pretty sensible.

Jim
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Thanks for your reply Paul.
It seems like I'm the only one who cares about this...
Maybe it is only an issue when you want to look at small stretches of a
long dataset. I personally ran into it when I wanted to look at small
stretches of a power spectrum of a very long time series.

I will only argue again that it seems logical to use a y-axis that spans
the range of values plotted, and that this therefore depends on xlim.

I guess I can use myplot() that behaves the way that seems sensible to
me.

Bill

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
The example I posted was artificial because my real example had 10,000
pts and I didn't want to post that. Basically I wanted to look at the
region surrounding one frequency of the spectrum where I expected a peak.
I couldn't see the peak because plot() had used the whole set of data to
pick the range for the y-axis.

There was of course a nice peak but it was invisible because this peak was
maybe 1/1000 as high as the maximum peak in the whole spectrum.
If you look around at other plotting programs out there I think you'll see
some doing what I propose. I think if you use small datasets the current
plot() behaviour will not cause problems. It's only a pain once you start
zooming in on small stretches.

Bill

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
"Paul Murrell" <p.murrell at auckland.ac.nz> writes:
- in S-PLUS you generally get a bunch of warnings for points that run
  off-scale - which presumably would teach you to do it with
  subsetting rather than clipping. (e.g. plot(y~x, subset=x>=a&x<=b))

- the default expressions for xlim/ylim would have to get rather
  complicated: ylim=if(!missing(xlim))range(y[x<=max(xrange) &
  x>=min(xrange)]) (and symmetrically for xlim). I'm not sure we want
  that for something as basic as plot().
#
On Mon, 23 Jul 2001, Bill Simpson wrote:

            
Oh, come on, many of us use *much* larger datasets.  Your problem is that
you are using xlim to zoom in, rather that subsetting the spectrum
object as the S language design intends (but the writer of plot.spec did
not anticpate).

You can of course set ylim as well as xlim ....
#
OK Brian and Peter point taken that S/R prefers that I do
plot(x[x>=1 & x<=10],y[x>=1 & x<=10])
rather than
plot(x,y,xlim=xrange)
Thanks for the replies.

(I am using my own spectrum routines)
Yes that's what I said in my original posting.

Bill

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Mon, 23 Jul 2001, Bill Simpson wrote:

            
(Too many days ago for me to have at hand.)   My point was that if you
want to `zoom in' then it seems logical to have to specify the zoom in
both x and y directions, not expect the x zoom to choose a y zoom.
3 days later
#
On 23 Jul 2001, at 11:18, Bill Simpson wrote:

            
Sorry to to join this thread so late but I was occupied and did not 
read my post a while.

I deal with similar sets of data with peaks and I use quite short 
function for interactive zooming.

Here it is:

replot_function(x,y)
{
body_locator(2)
dmx_min(body$x)
hmx_max(body$x)
dmy_min(body$y)
hmy_max(body$y)
plot(x,y,xlim=c(dmx,hmx),ylim=c(dmy,hmy),type="l")
}

It has to be called after plotting x,y and you shall pinpoint to opposit 
corners. I call it repetitively without any problems. Maybe it can help 
you.
Petr

petr.pikal at precheza.cz
p.pik at volny.cz

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Fri, 27 Jul 2001, Petr Pikal wrote:

            
range() will enable you to simplify this considerably.  Using the space
bar might make it readable.  (The recommended assignment operator is <- :
if you must use _ at least have spaces around it.  See Writing R
Extensions chapter 3 for how to tidy up your R source code.)

replot <- function(x, y, type="l")
{
   body <- locator(2)
   plot(x, y, xlim=range(body$x), ylim=range(body$y), type=type)
}