Daniel Anderson
Daniel Anderson

Reputation: 2424

reset par() in functions

When writing a plotting function in R, I'd like to not modify the global environment, so I include something like

op <- par()
on.exit(par(op))

But this is less than satisfactory because it spits out warning messages (e.g., "In par(op) : graphical parameter "cin" cannot be set"), but more importantly, it is not compatible with multi-panel plots. For example, if I had a simple function like

pfun <- function(x) {
    op <- par()
    on.exit(par(op))

    par(bg = "gray21", col = "deeppink", col.axis = "deeppink")
    plot(x, 
        xaxt = "n",
        yaxt = "n",
        col = "deeppink", 
        cex = 2, 
        pch = 22, 
        bg = "deeppink",
        col.lab = "deeppink")
    axis(1, col = "deeppink")
    axis(2, col = "deeppink")
}

it would work great for a single plot (apart from the warnings), but is incompatible with multi-panel plots, e.g.

par(mfrow = c(2, 2))
pfun(1:10)
pfun(10:1) # overwrites the first plot rather than plotting in the second panel

Is there a way to have the plot parameters reset on exit while also allowing for multi-panel plotting?

Upvotes: 9

Views: 3478

Answers (1)

dww
dww

Reputation: 31454

We can avoid interfering with multi-panel plots, by only saving /restoring the elements of par that we change in the function. In this case that means only storing bg, col, and axis.col. The important thing is to avoid interfering with the graphical parameters (particularly mfrow, mfcol and mfg) that control multiplot positions.

pfun <- function(x) {
  op <- par('bg', 'col', 'col.axis')
  on.exit(par(op))

  par(bg = "gray21", col = "deeppink", col.axis = "deeppink")
  plot(x, 
    xaxt = "n",
    yaxt = "n",
    col = "deeppink", 
    cex = 2, 
    pch = 22, 
    bg = "deeppink",
    col.lab = "deeppink")
  axis(1, col = "deeppink")
  axis(2, col = "deeppink")
}

Or, even slightly neater is to make use of the fact that when we set parameters with par it invisibly returns a list of the old values of the parameters we changed. So just the following will work nicely:

  op <- par(bg = "gray21", col = "deeppink", col.axis = "deeppink")
  on.exit(par(op))

Upvotes: 9

Related Questions