15

In Matlab, I would like to update the data plotted in a set of axes when the user zooms into the plot window. For example, suppose I want to plot a particular function that is defined analytically. I would like to update the plot window with additional data when the user zooms into the traces, so that they can examine the function with arbitrary resolution.

Does Matlab provide hooks to update the data when the view changes? (Or simply when it is redrawn?)

nibot
  • 14,428
  • 8
  • 54
  • 58

2 Answers2

18

While I have yet to find one generic "redraw" callback to solve this question, I have managed to cobble together a group of four callbacks* that seem to achieve this goal in (almost?) all situations. For a given axes object ax = gca(),

1. Setup the zoom callback function as directed by @Jonas:
set(zoom(ax),'ActionPostCallback',@(x,y) myCallbackFcn(ax));

2. Setup a pan callback function:
set(pan(ax),'ActionPostCallback',@(x,y) myCallbackFcn(ax));

3. Setup a figure resize callback function:
set(getParentFigure(ax),'ResizeFcn',@(x,y) myCallbackFcn(ax));

4. Edit: this one no longer works in R2014b, but is only needed if you add, e.g., a colorbar to the figure (which changes the axis position without changing the figure size or axis zoom/pan). I've not looked for a replacement. Finally, setup an undocumented property listener for the axes position property itself. There is one important trick here: We must hold onto the handle to the handle.listener object as once it's deleted (or leaves scope), it removes the callback. The UserData property of the axes object itself is a nice place to stash it in many cases.

hax = handle(ax);
hprop = findprop(hax,'Position');
h = handle.listener(hax,hprop,'PropertyPostSet',@(x,y) myCallbackFcn(ax));
set(ax,'UserData',h);

In all these cases I've chosen to discard the default callback event arguments and instead capture the axis in question within an anonymous function. I've found this to be much more useful than trying to cope with all the different forms of arguments that propagate through these disparate callback scenarios.

*Also, with so many different callback sources flying around, I find it invaluable to have a recursion check at the beginning of myCallbackFcn to ensure that I don't end up in an infinite loop.

Community
  • 1
  • 1
mbauman
  • 30,958
  • 4
  • 88
  • 123
  • 2
    As of R2014b according to the [official docs](http://de.mathworks.com/help/matlab/graphics_transition/why-does-handle-listener-return-an-error-1.html) `handle.listener` will not work anymore. – embert Jan 10 '15 at 11:10
9

Yes, it does. The ZOOM mode object has the following callbacks:

ButtonDownFilter
ActionPreCallback
ActionPostCallback

The latter two are executed either just before or just after the zoom function. You could set your update function in ActionPostCallback, where you'd update the plot according to the new axes limits (the handle to the axes is passed as the second input argument to the callback).

Jonas
  • 74,690
  • 10
  • 137
  • 177
  • Thanks, this is exactly what I was looking for! Is there also a generic redraw callback? – nibot Feb 09 '11 at 02:09
  • @nibot: You mean, like [`refresh`](http://www.mathworks.com/help/techdoc/ref/refresh.html)? Alternatively, `drawnow` flushes the queue. – Jonas Feb 09 '11 at 02:13
  • 1
    I meant, is there some way to make Matlab call a function that I specify whenever it redraws the figure? – nibot Feb 09 '11 at 02:17
  • @nibot: To my knowledge, there is no documented way to do that, as redrawing is pretty deep inside the entrails of Matlab. – Jonas Feb 09 '11 at 02:31