Skip to content

Unexpected behavior in par()

4 messages · Rui Barradas, Bill Dunlap

#
Hello,

I have a function using base graphics that changes some graphics 
parameters, then plots what it has to plot, then on exit puts the 
graphics parameters back as they were.
The problem is that if outside the function the graphics parameters are 
also changed, for instance mfrow, those chages are not respected by the 
function. This seems to come from the way the graphics pars are saved.

After par(mfrow = c(2, 1))

- if I call par(no.readonly = TRUE) then the second call to the function 
plots in the 1st row, it overplots what was plotted before.
- if I save the pars when they are changed, all is well.

Here is a reproducible example.


f <- function(x, ...) {
   old_par <- par(no.readonly = TRUE)    # this is the problem
   par(mar = c(4.1, 3.1, 3.1, 1.1))      # or maybe here
   on.exit(par(old_par))
   barplot(x, ...)
}

g <- function(x, ...) {
   old_par <- par(mar = c(4.1, 3.1, 3.1, 1.1))   # this is the solution
   on.exit(par(old_par))
   barplot(x, ...)
}

set.seed(2022)
b1 <- table(sample(4, 100, TRUE))
b2 <- table(sample(10, 100, TRUE))

# 1st function, unexpected behavior
old_par <- par(mfrow = c(2, 1))
f(b1, main = "1st plot")
f(b2, main = "2nd plot")
par(old_par)

# 2nd function, all is well
old_par <- par(mfrow = c(2, 1))
g(b1, main = "1st plot")
g(b2, main = "2nd plot")
par(old_par)


If I print(old_par) in any of the functions the result is the right 
mfrow setting, so I would expect the 2nd call to f() to plot in the 2nd 
row. But it doesn't.
Function f() calls par() twice but it only changes a parameter unrelated 
to the parameter set outside the function.

I'm obviously making a mistake but I don't know what. Is this expected 
(or a par() bug)?


Thaks in advance,

Rui Barradas
#
par("mfrow") works by updating par("fig") before each plot.  I think that
when you reset all the par values after each plot you reset par("fig") to
the value it had before you made the last plot.

-Bill
On Sat, Apr 2, 2022 at 10:45 AM Rui Barradas <ruipbarradas at sapo.pt> wrote:

            

  
  
#
Hello,

Thanks, that makes sense. So don't use par(no.readonly = TRUE) unless 
that's the desired behavior.

Rui Barradas

?s 20:00 de 02/04/2022, Bill Dunlap escreveu:
#
Making a new plot with par(mfrow=...) or par(mfcol=...) in effect also
updates par("mfg"), which describes where in the array of plots you are.
If you overwrite that with its previous value then you will overlay the new
plot on top of the previous one.

-Bill

On Sat, Apr 2, 2022 at 12:00 PM Bill Dunlap <williamwdunlap at gmail.com>
wrote: