I have difficulties setting exact axis limits at very small values.
For example, the following code:
A = 1e-1;
x=-1:0.1:1;
plot(x,A*x.^3)
ylim([-1 1]*A);
works as expected, i.e., creates a plot with y-axis limits exactly [-A A], only when A > 1e-8. For smaller values of A the resulting limits are approx. [-1.2*A 1.2*A].
// FIXME: maybe this test should also be relative?
else if (! logscale && (std::abs (limits(0) - limits(1)) < sqrt (eps)))
{
limits(0) -= 0.1 * std::abs (limits(0));
limits(1) += 0.1 * std::abs (limits(1));
do_update = true;
}
sqrt (eps) is sqrt (eps ("double")) (approx. 1.5e-8). That is most probably the cause why the axis limits are starting to get “weird” at this point.
The FIXME note was likely referring to something like your example…
I don’t recall the motivation for this code snippet. Possibly, I wanted to avoid same values for the upper and lower limits for, e.g., a single horizontal line in the axes. But the current test seems kind of arbitrary to me now…
At the same time, I’m not sure what would be a better test…
Edit: Maybe I thought about the condition that is used for log-scale axes when I wrote “should also be relative”? std::abs (std::log10 (limits(0) / limits(1))) < sqrt (eps)
That report is about setting limits at even lower values. At some point, we’d probably need to treat the limits as “basically the same” and automatically adjust them to get to something that can actually be reasonably rendered. But the current condition for that might be questionable…
We could either repurpose that report for that issue or open a new one.
Not sure if this condition is enough. IIUC, it would allow arbitrarily small distance between lower and upper limits as long as they are centered around zero. That won’t work at too small values because of the limited precision of single precision floating point numbers (even taking subnormals into account).
On the other hand, your condition does “approximately” the right thing when it comes to offsets of the data IIUC.