A couple of days ago, a reader of Matlab’s official Desktop blog asked whether it is possible to determine if an axes has been zoomed or not.
I have encountered this question myself some time ago, when I tried to customize a radar plot: The grid in radar plots does not automatically re-draw when the plot is zoomed, as in regular rectangular plots. Instead, the radial (angle) and circular (range) grid lines are statically painted when the plot is created, and remain fixed when the plot is zoomed or panned. Therefore, if we zoom in on a small-enough plot segment, we will not see any grid lines at all. It would be beneficial to repaint the grid-lines upon every zoom and pan event. I will not dive into the details today, but the important thing for today’s article is that the algorithm needed to know whether or not the axes is currently zoomed or not.
The official response is that this information is not readily available. We could of course store the axes limits somewhere and then compare them to the current limits in run-time. This will cause complications if the plotted data (and thereby the axes limits) change automatically during program use, even without any zooming/panning. It is also problematic if the user resets the zoom limits (as Jiro has correctly pointed out).
Today I’ll highlight another possible solution, that perhaps not many Matlab users are familiar with: Apparently, whenever zooming or panning occur, a hidden ApplicationData object is automatically added to the affected axes, with information about the original axes meta-data: limits, aspect ratio, camera info and view angles. This object is also automatically updated whenever we use zoom reset to reset the zoom limits.
So basically, all we have to do in run-time is to compare our current access limits with the stored info: if they are the same (or if the app-data object is missing) then the plot is unzoomed and unpanned; otherwise it is. So simple.
origInfo = getappdata(gca, 'matlab_graphics_resetplotview'); if isempty(origInfo) isZoomed = false; elseif isequal(get(gca,'XLim'), origInfo.XLim) && ... isequal(get(gca,'YLim'), origInfo.YLim) && ... isequal(get(gca,'ZLim'), origInfo.ZLim) isZoomed = false; else isZoomed = true; end
This still does not solve the problem of limit changes when the plot data is changed, but it may perhaps be a bit easier to use than manually storing the limits before plotting. (And yes, of course the if-else statement above could be made a one-liner logical construct, but I think this way is more readable).
Zooming and panning add some additional data to ApplicationData, and also use/modify some other hidden properties of the axes handle (use the getundoc function to see them). If you use one of them for any useful purpose, please report your usage in a comment below.