Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

Determining axes zoom state

November 10, 2011 11 Comments

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

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.

Related posts:

  1. Customizing axes part 5 – origin crossover and labels – The axes rulers (axles) can be made to cross-over at any x,y location within the chart. ...
  2. Axes LooseInset property – Matlab plot axes have an undocumented LooseInset property that sets empty margins around the axes, and can be set to provide a tighter fit of the axes to their surroundings....
  3. Setting axes tick labels format – Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...
  4. Enabling user callbacks during zoom/pan – Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...
  5. Customizing axes part 3 – Backdrop – Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...
  6. Customizing axes part 4 – additional properties – Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...
Handle graphics Hidden property Pure Matlab
Print Print
« Previous
Next »
11 Responses
  1. Richard November 12, 2011 at 04:03 Reply

    Hi Yair, I am the original asker on the blog, I thought I’d repeat my comment here. The main reason I want to know this is because I’m developing a code to automatically produce ‘tight’ figures without excess space around them for publication. I also want this code to work for subplots by getting the minimum required bounding box (based on the ‘TightInset’ and ‘Position’ properties) of every axes in the figure. My problem is, if a 3D plot has been zoomed, these properties are no longer useful, and the figure should be ignored, or left as it is. 2D plots that have been zoomed are fine, as the axes stay where they are in the figure, but the whole view of the figure changes if any 3D axes have been zoomed. I have found a way to determine if an axes is 3D, using the view function. Perhaps using your tips I can get the last part.

    P.S. I’ve read quite a few of your blog articles over the last year or so, it’s been very useful, thanks!

    • Yair Altman November 12, 2011 at 08:34 Reply

      @Richard – take a look at the undocumented hidden axes property LooseInset: http://undocumentedmatlab.com/blog/axes-looseinset-property/

  2. Aleksander Hammernes May 9, 2014 at 04:46 Reply

    Would it be possible to get the zoom area ?
    let say you activate the zoom function in a axes, normally this off course works fine, you can click and drag your mouse inside
    the axes, and it zoom`s the axes to your wishes. how ever not in my gui…… in need to replot to make it work for me, so is there a
    way to “capture” the x and y limits from the drag dragable zoom ?

    • Yair Altman May 9, 2014 at 06:47 Reply
      xlimits = get(hAxes,'xlim');
      ylimits = get(hAxes,'ylim');

      xlimits = get(hAxes,'xlim'); ylimits = get(hAxes,'ylim');

  3. Adam October 10, 2014 at 03:14 Reply

    Hi Yair. Do you know if something has changed in R2014b that would cause this to no longer work when the figure containing the axes is not yet visible when zoom reset is called? It is one of a number of related things in my code that has broken from R2014a all seemingly related to whether or not a figure is actually visible yet or whether it is the figure in focus. I fixed this case by just checking if the zoominfo object is empty (it is now in R2014b, it wasn’t in R2014a when triggered from the OpeningFcn) and another case where creating a zoom object without an explicit figure used to match to the correct figure by default in R2013a, but picked up the figure that spawned it instead in R2014b was easy to fix.

    I couldn’t see anything in the described graphics changes though that would explain this behaviour. My troubles with findjobj also seem to relate to this type of issue, seemingly EDT effects that were not present in R2014a, but now break the code in R2014b. In that case I just had to stop using the functionality, at least until I have more time to investigate. The axis zoom state information in this blog has been very useful to me though so thank you for sharing.

    • Yair Altman October 10, 2014 at 03:16 Reply

      @Adam – there are numerous small changes in 14b that are not officially documented. I guess this is yet another example.

  4. Eduard Braun September 12, 2015 at 15:30 Reply

    This is a very interesting way to determine if the axes are zoomed.

    However I’m wondering if it is possible to do this the other way round: Start with unzoomed axes and programmatically bring them into a state as if they were zoomed in by the user?

    For clarification: If I simply set XLim and/or YLim on the axes I can zoom in a portion of the graph but the user can not zoom out anymore… Therefore it’s not the same as if the user zoomed in (since then he obviously can zoom out again).

    • Yair Altman September 13, 2015 at 00:17 Reply

      @Eduard – you can use the zoom function with a certain factor, for example, zoom(2.5)

    • Eduard Braun September 13, 2015 at 07:03 Reply

      Thanks for feedback!

      I had looked at zoom before but sadly it doesn’t allow set specific numeric limits on the axes which makes it useless for many cases.

      However it turned out the actual solution is pretty simple:
      1. Set the limits of the axes to the desired “zoomed out” state by setting appropriate limits.
      2. Use zoom(figure,'reset') – this is were the “magic” happens and the current state of the figure is internally saved as the completely zoomed out state.
      3. Achieve the desired zooming by simply setting appropriate limits on the axes.

      Steps 1 and 3 look redundant (and one would actually end up with the same visible content when just executing step 3.), however if one omits steps 1. and 2. it would not be possible to manually zoom out of the figure again!

  5. Adee Ran May 29, 2016 at 18:32 Reply

    Thanks for exposing this (yet another) undocumented feature!

    I used a variant to set the “original zoom” of only the horizontal axis – which “zoom reset” does not seem to support:

    rpv = getappdata(gca, 'matlab_graphics_resetplotview');
    rpv.XLim = [tmin tmax]; % Use values calculated elsewhere
    setappdata(gca, 'matlab_graphics_resetplotview', rpv);

    rpv = getappdata(gca, 'matlab_graphics_resetplotview'); rpv.XLim = [tmin tmax]; % Use values calculated elsewhere setappdata(gca, 'matlab_graphics_resetplotview', rpv);

    Works like a charm.

  6. tim July 4, 2016 at 07:10 Reply

    The suggested solution seems to fail when zoom is constrained to only one axis and/or zoom mode is changed. Not all lim fields exist in ‘matlab_graphics_resetplotview’ for constrained axis zoom (so testing the others will throw an error). It also seems that fields are not updated when zoom mode is changed (eg from horizontal to unconstrained). A change in mode can however be detected by comparing gca’s limmode for each axis to those in matlab_graphics_resetplotview. But I don’t think it is then possible to tell if the current zoom value (ie lim) is different to its original setting if that axis did not have its zoom mode on originally.
    A minimalist solution would be to store the 3 axes’ limits on creation.

    NB r2016a

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitable (6) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top