mfg, mfcol, mfrow, and layout() – secret friends

[This article was first published on Odd Hypothesis, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

I was working on an issue (enhancement) today in my groan R-package today that required adding additional plotting elements via lines() and points() to a device that had already been partitioned by layout(). The code I wanted to use was essentially:

<span class="com"># Y and S are lists of xy.coords() objects of the same length</span><span class="pln"><br /><br />lyt </span><span class="pun">=</span><span class="pln"> matrix</span><span class="pun">(</span><span class="lit">1</span><span class="pun">:</span><span class="pln">length</span><span class="pun">(</span><span class="pln">Y</span><span class="pun">),</span><span class="pln"> ncol</span><span class="pun">=</span><span class="lit">10</span><span class="pun">)</span><span class="pln"><br />layout</span><span class="pun">(</span><span class="pln">mat</span><span class="pun">=</span><span class="pln">lyt</span><span class="pun">)</span><span class="pln"><br /><br /></span><span class="com"># function A</span><span class="pln"><br /></span><span class="com"># plot Y first as points</span><span class="pln"><br />lapply</span><span class="pun">(</span><span class="pln">Y</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">x</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"><br />  plot</span><span class="pun">(</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...)</span><span class="pln"><br /></span><span class="pun">})</span><span class="pln"><br /><br /></span><span class="com"># function B</span><span class="pln"><br /></span><span class="com"># overlay S as lines on the grid of plots for Y</span><span class="pln"><br />lapply</span><span class="pun">(</span><span class="pln">S</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">x</span><span class="pun">){</span><span class="pln"><br />  lines</span><span class="pun">(</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...)</span><span class="pln"><br /></span><span class="pun">})</span>

However, I would only get all of the above lines in one subplot. For a brief moment, I considered rewriting my whole set of plotting methods to use split.screen() or par(mfcol). Ugh!

On a whim, I decided to check what par('mfg') would return after a device had been partitioned and plotted to with:

<span class="pln">layout</span><span class="pun">(</span><span class="pln">matrix</span><span class="pun">(</span><span class="lit">1</span><span class="pun">:</span><span class="lit">9</span><span class="pun">,</span><span class="pln"> nrow</span><span class="pun">=</span><span class="lit">3</span><span class="pun">))</span><span class="pln"><br />par</span><span class="pun">(</span><span class="pln">mar</span><span class="pun">=</span><span class="pln">c</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="lit">0</span><span class="pun">))</span><span class="pln"><br />plot</span><span class="pun">(</span><span class="pln">runif</span><span class="pun">(</span><span class="lit">10</span><span class="pun">))</span>

I was pleasantly surprised to find:

<span class="pun">></span><span class="pln"> par</span><span class="pun">(</span><span class="str">'mfg'</span><span class="pun">)</span><span class="pln"><br /></span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="lit">3</span>

indicating that I could potentially direct the next plot in a layout()‘ed device by setting the value of mfg= to the next plot id:

<span class="pln">lyt </span><span class="pun">=</span><span class="pln"> matrix</span><span class="pun">(</span><span class="lit">1</span><span class="pun">:</span><span class="lit">9</span><span class="pun">,</span><span class="pln"> nrow</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"><br />par</span><span class="pun">(</span><span class="pln">mfg</span><span class="pun">=</span><span class="pln">which</span><span class="pun">(</span><span class="pln">lyt </span><span class="pun">==</span><span class="pln"> </span><span class="typ">NextPlotID</span><span class="pun">,</span><span class="pln"> arr</span><span class="pun">.</span><span class="pln">ind</span><span class="pun">=</span><span class="pln">TRUE</span><span class="pun">)[</span><span class="lit">1</span><span class="pun">,])</span>

Unicorns and rainbows, this works! (despite all the dire warnings in the documentation regarding incompatibilities)

Thus, the resulting code:

<span class="com"># Y and S are lists of xy.coords() objects of the same length</span><span class="pln"><br /><br />lyt </span><span class="pun">=</span><span class="pln"> matrix</span><span class="pun">(</span><span class="lit">1</span><span class="pun">:</span><span class="pln">length</span><span class="pun">(</span><span class="pln">Y</span><span class="pun">),</span><span class="pln"> ncol</span><span class="pun">=</span><span class="lit">10</span><span class="pun">)</span><span class="pln"><br />layout</span><span class="pun">(</span><span class="pln">mat</span><span class="pun">=</span><span class="pln">lyt</span><span class="pun">)</span><span class="pln"><br /><br /></span><span class="com"># function A</span><span class="pln"><br /></span><span class="com"># plot Y first as points</span><span class="pln"><br />lapply</span><span class="pun">(</span><span class="pln">Y</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">x</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"><br />  plot</span><span class="pun">(</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...)</span><span class="pln"><br /></span><span class="pun">})</span><span class="pln"><br /><br /></span><span class="com"># function B</span><span class="pln"><br /></span><span class="com"># overlay S as lines on the grid of plots for Y</span><span class="pln"><br />lapply</span><span class="pun">(</span><span class="pln">seq_along</span><span class="pun">(</span><span class="pln">S</span><span class="pun">),</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">n</span><span class="pun">){</span><span class="pln"><br />  par</span><span class="pun">(</span><span class="pln">mfg</span><span class="pun">=</span><span class="pln">which</span><span class="pun">(</span><span class="pln">lyt </span><span class="pun">==</span><span class="pln"> n</span><span class="pun">,</span><span class="pln"> arr</span><span class="pun">.</span><span class="pln">ind</span><span class="pun">=</span><span class="pln">TRUE</span><span class="pun">)[</span><span class="lit">1</span><span class="pun">,])</span><span class="pln"> </span><span class="com"># sets next plot in grid!</span><span class="pln"><br />  lines</span><span class="pun">(</span><span class="pln">S</span><span class="pun">[[</span><span class="pln">n</span><span class="pun">]],</span><span class="pln"> </span><span class="pun">...)</span><span class="pln"><br /></span><span class="pun">})</span>

and issue resolved.

Written with StackEdit.

To leave a comment for the author, please follow the link and comment on their blog: Odd Hypothesis.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)