0

One of the things that most bugs me about R is the separation of the plot, points, and lines commands. It's somewhat irritating to have to change plot to whatever variant for the first plot done, and to have to replot from scratch if you failed to have set the correct the ylim and xlim initially. Wouldn't it be nice to have one command that:

  1. Picks lines, points or both via an argument, as in plot(..., type = "l") ?

  2. By default, chooses whether to create a new plot, or add to an existing one according to whether the current device is empty or not.

  3. Rescales axes automatically if the added elements to the plot exceed the current bounds.

Has anyone done anything like this? If not, and there's no strong reason why this isn't possible, I'll answer this myself in a bit...

Fhnuzoag
  • 3,810
  • 2
  • 20
  • 16
  • 2
    You are describing the base graphics system. Your two alternatives, i.e. `lattice` and `ggplot2` use grid graphics and are more flexible and powerful. What you describe is rather easy to do with `ggplot2`. – Andrie Oct 23 '12 at 09:22
  • 1
    ggplot2 and lattice both have their advantages and disadvantages. But in general, both require a new way of doing things, and especially do not play nicely with adding new plot elements later using `lines` and `points` and doing combined multiplots with some plots using the base graphics system (which comes up with packages that do their own plots). I think, anyway? – Fhnuzoag Oct 23 '12 at 09:58
  • `lattice` and `ggplot2` both use `grid` graphics, so you're correct - this doesn't mix with base graphics. But that doesn't prevent you from adding new elements using `grid` versions of line and point, or to simply extend the plot within the current plot paradigm. – Andrie Oct 23 '12 at 10:07
  • Well, sure, but not wanting to learn `grid` graphics prevents you. :) That and people who have implemented application specific base graphics-based plot/lines/points commands in their packages, that you would have to rewrite to make work with grid plots. – Fhnuzoag Oct 23 '12 at 10:18

2 Answers2

1

Some possible functionality that may help with what you want:

The matplot function uses base graphics and will plot several sets of points or lines in one step, figuring out the correct ranges in one step.

There is an update method for lattice graphics that can be used to add/change things in the plot and will therefore result in automatic recalculation of things like limits and axes.

If you add additional information (useing +) to a ggplot2 plot, then the things that are automatically calculated will be recalculated.

You already found zoomplot and there is always the approach of writing your own function like you did.

Greg Snow
  • 48,497
  • 6
  • 83
  • 110
0

Anyway, this is what I came up with: (It uses zoomplot from TeachingDemos)

 fplot <- function(x, y = NULL, type = "l", new = NULL, xlim, ylim, zoom = TRUE,...){
   require(TeachingDemos)
   if (is.null(y)){
if (length(dim(x)) == 2){
    y = x[,2]
    x = x[,1]
} else {
       y = x
       x = 1:length(y)
     } 
}

   if ( is.null(new) ){
   #determine whether to make a new plot or not
   new = FALSE
   if (is.null(recordPlot()[[1]])) new = TRUE
   }
   if (missing(xlim)) xlim = range(x)
   if (missing(ylim)) ylim = range(y)

   if (new){
   plot(x, y, type = type, xlim = xlim, ylim = ylim, ...)
   } else {
    if (type == "p"){
        points(x,y, ...)
    } else {
        lines(x,y, type = type, ...)
    }
    if (zoom){
    #rescale plot
    xcur = par("usr")[1:2]
    ycur = par("usr")[3:4]
    #shrink coordinates and pick biggest
    xcur = (xcur - mean(xcur)) /1.08 + mean(xcur)
    ycur = (ycur - mean(ycur)) /1.08 + mean(ycur)
    xlim = c(min(xlim[1], xcur[1]), max(xlim[2], xcur[2]))
    ylim = c(min(ylim[1], ycur[1]), max(ylim[2], ycur[2]))
    #zoom plot
    zoomplot(xlim, ylim)
    }
   }
 }

So you can do, e.g.

dev.new()
fplot(1:4)
fplot(1:4 +1, col = 2)
fplot(0:400/100 + 1, sin(0:400/10), type = "p")
dev.new()
for (k in 1:20) fplot(sort(rnorm(20)), type = "b", new = (k==1) )

par(mfrow) and log axis don't currently work well with zooming, but, it's a start...

Fhnuzoag
  • 3,810
  • 2
  • 20
  • 16