3

I have an existing plotting function (perhaps written by someone else) that uses mfrow to plot multiple figures on the same graphics device. I want to edit figures that have already been plotted (e.g. perhaps add a reference line to figure 1)

par(mfrow = c(1, 2))
plot(1:10)
hist(1:10)
# Oh no!  I want to add abline(a = 0, b = 1) to the first plot!

Assume this code is nested in another plotting function PlotABunchOfStuff(1:10) that I can't modify.

I don't want to modify PlotABunchOfStuff because someone else owns it, or I'm just debugging and won't need the extra details once the bug is found.

Steven Scott
  • 481
  • 3
  • 14

3 Answers3

1

Use par(mfg).

For example:

par(mfrow = c(2, 3))

for (i in 1:6) {
  plot(i, xlim = c(0,7), ylim = c(0, 7))
}

par(mfg = c(2, 2))
points(3,3,col= "red")

par(mfg = c(1, 1))
points(3,3,col= "blue")
Gimelist
  • 791
  • 1
  • 10
  • 25
0

If you are ready to use ggplot I think you can find what you want in the code below :

df <- data.frame(x = 1:10, y = 1:10)
g1 <- ggplot(df, aes(x = x, y = y)) +
  geom_point()
g2 <- ggplot(df, aes(x = x, y = y)) +
  geom_line()

grid.arrange(g1, g2)

g1 <- g1 + geom_smooth(method='lm',formula=y~x)  # it could be anything else !

grid.arrange(g1, g2)

Edit 1

Create a graphical object in windows which will be destroye after dev.off() if filename = "" :

win.metafile(filename = "")

By default inhibit doesn't allow the plot to be recorded so we use enable :

dev.control('enable')
plot(1:10)
p <- recordPlot() 
dev.off()
replayPlot(p)

p
abline(a = 1, b = 1, col = "red")
p <- recordPlot() 
dev.off()
replayPlot(p)

My inspirations on Stackoverflow :

R plot without showing the graphic window Save a plot in an object

My inspirations on R :

https://www.rdocumentation.org/packages/grDevices/versions/3.6.0/topics/dev https://www.rdocumentation.org/packages/grDevices/versions/3.6.0/topics/recordPlot

I hope it helps you ! Good luck.

Rémi Coulaud
  • 1,684
  • 1
  • 8
  • 19
  • Thanks, but the existing plot function (which is quite elaborate) is already in base R graphics. The ggplot solution is nice (and similar to python), but I'm really interested in base R. It can be done (I did it once, but forgot how), but it is obscure. – Steven Scott May 28 '19 at 22:05
0

Be careful with scaling!

For the example in the original question, this will not have the result I think is desired.

par(mfrow = c(1, 2))
plot(1:10)
hist(1:10)
par(mfg = c(1, 1))
abline(a = 0, b = 1)

But this will have the result I think is desired.

par(mfrow = c(1, 2))
plot(1:10)
hist(1:10)
par(mfg = c(1, 1))
plot.window(xlim = c(1, 10), ylim = c(1, 10))
abline(a = 0, b = 1)

The mfg graphics parameter will allow you to jump to any panel, but the window scaling may need to be adjusted to be appropriate for the scale used when the original plot was created in that panel.