title: R: set axis ticks & range to include all points w/ pretty breaks
body: <p>I have a function which builds line plots dynamically, hence need to solve my problem with a formula rather than manually setting ranges. (note to experts: I've written this in logical progression for myself &amp; others later - apologies that this means more text; I find R help to be particularly fragmented and unhelpful for plotting, so hopefully this will help others).</p>
  
  <p>The axes for the line plots I've generated have the right kinds of numbers of tick spacings (default, assumedly 'pretty breaks'?) but the axis range doesn't encompass the whole range of the data - some are outside. (you can ignore the rug plot deciles above the axis, though the first &amp; last ones show the data range)</p>
  
  <p><img src="https://i.stack.imgur.com/DbkLs.png" alt="x axis length"></p>
  
  <p>So what I'd like is for the x axis width to encompass all of the data, but retain the pretty breaks, i.e. spread the min/max tick points out to nice values at or past the extreme values... ideally without lots of work! I don't mean to sound lazy, but it feels like something that would be a common desire. I was reading about <code>at</code>, including <code>pretty</code> and <code>axTicks</code>, also <code>xaxt</code> and <code>xaxs</code> and <code>xpd</code>.</p>
  
  <p>In <code>plot</code>, <code>xaxs</code> controls the width the actual data line takes up within the plot, "i" extending it to the margins and "r" (or default) squeezing it in a little. Which is cool to know, but arguably isn't the 'axis' as one would expect. (setting here is "r"/default)</p>
  
  <p>Help for <code>xaxt</code> lets one know that it's what you use to turn axis plotting off, but doesn't say what else it does / what they other types are.</p>
  
  <p>In <code>axis</code>, <code>at</code> controls the axis line length, defaulting to <code>axTicks</code>, which defaults to <code>xaxp</code>. On the face of it, <code>xaxp</code> is what I want, allowing one to specify <code>c(x1, x2, n)</code>, however the default <code>x1</code> &amp; <code>x2</code> are inside the data range, rather than encompassing it.</p>
  
  <p><code>axis</code> help says:</p>
  
  <p>"The axis line is drawn from the lowest to the highest value of <code>at</code>, but will be clipped at the plot region. By default, only ticks which are drawn from points within the plot region (up to a tolerance for rounding error) are plotted, but the ticks and their labels may well extend outside the plot region. Use <code>xpd = TRUE</code> or <code>xpd = NA</code> to allow axes to extend further"</p>
  
  <p>Neither <code>xpd = TRUE</code> nor <code>xpd = NA</code> seem to change anything. xpd help says:</p>
  
  <p>"If FALSE, all plotting is clipped to the plot region, if TRUE, all plotting is clipped to the figure region, and if NA, all plotting is clipped to the device region"</p>
  
  <p>I.e. <code>axis</code> help says <code>xpd</code> controls axis extension, <code>xpd</code> help says <code>xpd</code> controls plotting clipping.</p>
  
  <p><code>xaxp</code> help says "See <code>axTicks()</code> for a pure R implementation of this"</p>
  
  <p><code>axTicks</code> "computes pretty tickmark locations, the same way as R does internally", and defaults to the <code>at</code> values for the relevant side, i.e. <code>par("xaxp")</code>.</p>
  
  <p><code>pretty</code> seems scarily complex, and may well be what <code>R</code> uses internally to calculate the default tick spacing when applied to <code>at</code>; it would be cool to be able to edit the <code>n</code> argument of that and nothing else, i.e. specify the desired number of intervals given my plotting area size, but I'm happy to leave that if it means spending a day decompiling, understanding, then manually recompiling <code>pretty</code>! Also I wouldn't know whether the <code>n</code> of ticks in pretty does the same thing as <code>n</code> in <code>xaxp</code>, and which takes priority if so.</p>
  
  <p>So: R help seems to use "axis" to mean both axis (<code>xaxt</code>, <code>axis</code>) and plotting (<code>xaxs</code>, <code>xpd</code>), there's no indication whether the parameter is controlled by <code>par</code>, <code>plot</code>, <code>axis</code>, or can be controlled by some combination of any of them (as usual). In trying to find the element responsible, <code>axis</code> says <code>at</code> which says <code>axTicks</code> which says <code>xaxp</code> which says <code>axTicks</code> which says <code>at</code> (= loop).</p>
  
  <p>As a secondary, broader, meta question: am I doing something wrong here in terms of trying to find the answer to plotting problems? I read and read and the help is so regularly lacking, confusing, contradictory, and usually leads to an intuition black hole as to whether something should be controlled by <code>par</code>, <code>plot</code> or <code>axis</code>. Thanks in advance guys. Sorry this is long, I genuinely thought this would be a super simple option.</p>
  
  <p>Minimal reproducible example:</p>
  
  <pre><code>png(filename="A.png", width=4*480, height=4*480, units="px", pointsize=80, bg="white", res=NA, family="", type="cairo-png")
  par(mar=c(1.32,2,0.4,0.5), fig=c(0,1,0,1), las=1, lwd=8, bty="n", mgp=c(2,0.5,0), xpd=NA)
    plot(ChickWeight[,1:2],type="l",xaxs="i",yaxs="i")
  dev.off()
  </code></pre>