Zooming in figures has been around forever. There are a couple of neat zoom enhancements, though, that may have snuck in under your radar (you didn't read the release notes?!). Between MATLAB 7.0 (R14) and MATLAB 7.3 (R2006b) we added the ability to link two axes, constrain a zoom and customize a zoom. Here are a few examples to help you get started.
Contents
Zooming an Axes
We'll start by plotting some data. I'll use one of my favorite data sets, the magic square:
ax = axes; p = plot(ax,magic(3));
To enter zoom mode, I can click on the toolbar button shaped like a magnifying glass.
Alternatively, I can enter the mode from the command-line.
zoom on;
For the purposes of this posting, whenever I wish to zoom, I'll do so programatically, and by a factor of two.
zoom(2);
Linking two Axes
Simply using the zoom tool, I am able to explore a data set that exists in a single axes. You might ask, however,
"What if I have two subplots with data that is related? If I zoom in on one plot, can I have the other one follow suit?"
That's an excellent question. I'm glad you asked. Let's create two sequences of data that share a domain, but but live in different ranges.
x1 = -2*pi:0.1:2*pi; y1 = sin(x1); x2 = -4*pi:0.1:4*pi; y2 = cos(x2)*100; ax(1) = subplot(1,2,1); plot(ax(1),x1,y1); ax(2) = subplot(1,2,2); plot(ax(2),x2,y2);
I can now link these two axes
linkaxes(ax,'x');
From this point onwards, if the limits of one x-axis change (perhaps due to a zoom operation), the limits of the second axes will follow.
Constraining the Zoom
In addition to linking axes, we can also constrain the zoom direction. For example, I may not want to zoom the y-axis of either one of my subplots.
zoom xon;
zoom(2);
Customizing the Zoom
It may happen, however, that the two data sets I've plotted do not share a domain or range, but are correlated in some way. In this case, I need to do a bit more work to build a relationship. Let's begin by getting the zoom object for the figure.
hZoom = zoom(gcf); get(hZoom)
ButtonDownFilter: []
ActionPreCallback: []
ActionPostCallback: []
Enable: 'on'
FigureHandle: [1x1 figure]
Motion: 'horizontal'
Direction: 'in'
RightClickAction: 'PostContextMenu'
UIContextMenu: []
From this object, we can get some information about the state of the figure. For example, we see that zoom mode is on, and constrained to be horizontal (x-only).
There are also callbacks that may help us further customizing the zoom behavior of these two axes. When the axes were linked, I lost some information in the second axes. I would much prefer that the second axes zooms twice as much as the first and the first zooms half as much as the second. To enforce this relationship, I can use the "ActionPostCallback" property of the object.
set(hZoom,'ActionPostCallback',{@halfZoom,ax}); dbtype halfZoom.m
1 function halfZoom(fig,evd,ax) %#ok<INUSL> 2 % Zoom one axes by a factor of two from the other: 3 4 currentAxes = evd.Axes; 5 if currentAxes == ax(1) 6 % If we are zooming the left axes, zoom the right axes by twice as 7 % much: 8 newLim = get(currentAxes,'XLim'); 9 set(ax(2),'XLim',newLim*2); 10 else 11 % If we are zooming the right axes, zoom the left axes by half as much: 12 newLim = get(currentAxes,'XLim'); 13 set(ax(1),'XLim',newLim/2); 14 end
The event data of the callback tells me which axes I've zoomed in on. From there, I can obtain the axes limits and perform the necessary calculations to enforce this relationship.
linkaxes(ax,'off'); set(ax,'XLimMode','auto'); zoom(2);
Using the zoom object, I am also able to prevent an axes from being zoomed or have it only zoom in a particular direction.
setAllowAxesZoom(hZoom,ax,false);
At this point, there will be no change to the figure if I attempt to zoom in either axes.
Using Zoom in a Custom Application
Using the zoom object, it is now possible to take advantage of zooming behavior in a custom application. For example, we can construct a figure containing an overview axes. Whenever I zoom in on the main axes, I am able to see where I am in my data.
overviewPlot(gcf,magic(3)); set(gcf,'Color','w'); zoom on; zoom(2);
The code to the "overviewPlot" function can be found on the File Exchange here.
Similar features exist for the "pan" and "rotate3d" functions. What sorts of customizations would you like to be able to accomplish using these tools?
Here's a video that demonstrates how to use the overviewPlot function. Thanks to Doug (of Doug's Pick of the Week) for recording this.
-by Dan Sternberg, The MathWorks
This blog entry was written using the MATLAB publishing feature.
Get
the MATLAB code
Published with MATLAB® 7.5



what about linking axes that are not both x or y?
x = magic(3)
ax(1) = subplot(4,1,1);
plot(ax(1),x(1,:),x(2,:));
ylabel(’y1′);
ax(2) = subplot(4,1,2);
plot(ax(2),x(1,:),x(3,:));
ylabel(’y2′)
ax(2) = subplot(4,1,[3 4]);
plot(ax(2),x(2,:),x(3,:));
xlabel(’y1′);
ylabel(’y2′);
so here the top two plots have the same ylim (0 to 10) but when that y data is cross-plotted at the bottom, the xlim (3 to 7) and ylim are not the same (2 to 10)?
i make plots like this quite frequently, but would like to automatically make those axes (y1 and y2) the same when they are at the top and at the bottom.
thanks,
jason.
Hi Jason,
Currently, it is not possible to link two different directions together. I have logged this as an enhancement request in our database for consideration in a future release. Currently, the closest thing to do is use the “ActionPostCallback” to ensure the relationship between the axes manually.
-Dan
What about zooming on axes that have been “dateticked” ?
dts=(now-99:now)’;w=exp(.2^2*(1:100)’/2+.2*cumsum(randn(100,1)));
figure;plot(dts,w,’linewidth’,2);datetick
zoom(2)
the ticks are lost (no automatic redraw of them)…
Currently, datetick does not refresh the axes limits and ticks after a zoom operation. This is something that we are working on for a future release. In the meanwhile, it is possible to work around this issue by using the callbacks of the pan and zoom object as in this File Exchange posting:
http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15029&objectType=file
-Dan
Good job
please tell my if can use this software to study thy number of periods in dynamic system
Linking axes and constrained zooming are both very powerful capabilities that I am used to in Simulink scopes. I always thought (and still do think) that Matlab should include additional toolbar buttons to link axes and constrained zooming, so I created the following Shortcuts on my Matlab toolbar. Each shortcut is applied to the current figure.
X Zoom
>>zoom xon
Y Zoom
>>zoom yon
Link X Axes
(I use this all the time, but unfortunately the syntax of the function requires the handles of all the subplots which may not be immediately known in order to link axes in the x or y direction. Therefore, I swiped some code out of the top of linkaxes and created a shortcut with the following code.)
>>fig = get(0,’CurrentFigure’);
>>if isempty(fig), return; end
>>ax = findobj(fig,’Type’,'Axes’);
>>nondatachild = logical([]);
>>for k=length(ax):-1:1
>>nondatachild(k) = isappdata(ax(k),’NonDataObject’);
>>end
>>ax(nondatachild) = [];
>>linkaxes(ax,’x')
Pat,
It’s not often that people talk about how the simulink scopes are more powerful than a regular figure window :-). Another option, although I am not sure if it is less work, would be to use the new toolbar editor to create icons for a toolbar in a MATLAB GUI to do the same things.
What about two images? Can I link their horizontal axes?
Wenjian,
You can link axes containing two images using the syntax
linkaxes(ax,’x')
where “ax” is a vector containing the handles to the two axes.
I’d really like to be able to put a zoomed in version of part of the figure inside the original figure, so that one can see the overview, as well as details of some interesting part at the same time.
I was trying to do zoom, then copy object, but zoom always affect all lines in the same plot. Maybe I should consider overlaying two plots in the same figure? Haven’t found anything about this yet.
Bao -
Check out Doug Hull’s excellent Zoom Box: http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=2884&objectType=FILE
-scott
Hi,
I have a couple of questions…
I would like to be able to zoom in and out by a factor that is much larger than 2, but sometimes it does not work. How would I be able to do that?
I have tried to zoom in by adjusting the axis range/limits (e.g. by changing the max x-axis limit from 0.14 to 10e-9), or by dragging a box using the zoom-microscope (instead of the ‘hand’ tool). However, most of the time the result is only the area I’ve selected, at its original size! How can I blow up the small area I selected to be as large as the usual figure size? How come in some cases changing the axis range/limits does not seem to work?
Perplexed,
J
@J,
It’s difficult to explain what is going on without seeing your graph or the exact commands you are using. If you are using a standard line plot, it’s possible that the zoomed in region has the same shape as the original plot. This happens a lot when you zoom in on a plot that does not have a lot of actual data points or does not vary much from point to point. One way to verify that your plot is zooming is when using the interactive tools to see the axes labels change. Depending on the range and label, it may not look like much is happening, also sometimes it can only be seen by the exponent multiplier at the edge of the axis.