I would like to add code in my function to zoom around a point, while keeping the option to un-zoom manually later.
I can use set(gca,'xlim',[x1 x2]), but if I later try to get back to the original zoom using the magnifier glass, the axes are "stuck".
Maybe not as elegant as you want, but you can store the original axis limits:
plot(rand(100));
xlim_orig = xlim();
ylim_orig = ylim();
% Zoom to point ...
% Do other stuff
% Zoom back out
xlim(xlim_orig)
ylim(ylim_orig)
Once you have "reset" the axes limits, the manual zoom and pan tools will work as expected.
Related
First, when I use inputdlg, Matlab does not let me to zoom in on my figure.
Second, when I enter a number using the command and try to convert it to cell using num2cell, I get this error: 'error using cellstr input must be a string'.
This is the piece of code that I am using:
No = cell2mat(inputdlg('Type in number: '));
(this is where I can't zoom in anymore!)
prompt = num2cell(1:2*No);
title = 'Numbers';
answer = inputdlg(prompt,title);
(this is where I get the error!)
Do you have any ideas how I can resolve these issues? I am using Matlab on a Mac system.
To programmatically zoom in or zoom out in a figure, you can use the zoom function.
An example could be:
% Create a Figure
my_fig=figure
% Plot something in the figure
plot(randi(10,10,1))
grid minor
% Get the zoom factor
zoom_factor=str2double(inputdlg('Type in number: '))
% Zoom the axes of the selected factor
zoom(my_fig,zoom_factor)
This will zoom in the plot by the value defined in the inputdlg.
The zoom will be action will be centered in the center of the axes, as it happens when you select the zoom icon in the figure toolbar and click on the centre of the figure.
Also, you can simply call
% Enable zooming
zoom(my_fig,'on')
to enable the zoom, this has the same effect than clicking on the zoom icon on the figure toolbar.
If you want to zoom a particular area of the graph, you can change the values of xlim and ylim.
With respect to the plot created in the example, you can use inputdlg to get the new limits and then update the plot
In this case, you have to input the 4 values in the inputdlg separated by a space (e. g. 2.5 5.5 5.5 7.5)
% Get the axes handle
ax=gca;
% Store the original X anf Y Limit
orig_xlim=ax.XLim;
orig_ylim=ax.YLim;
zoom_factor=inputdlg('Type in new lim: ')
new_lim=str2num(char(zoom_factor))
ax.XLim=[new_lim(1) new_lim(2)];
ax.YLim=[new_lim(3) new_lim(4)];
Having stored the original values of the limits, you zoom out setting back them.
Here's my problem: I have an axes object in a figure.
The user can draw a bunch of points on the image.
Up to this point, everything is working as it should.
Now the user shall be able to zoom, draw some points on the zoomed image, and revert back to the original image once he/she has done.
I have a function updateVisualization that is called every time there is a change on the axes made by the user.
In this function, I tried to use
zoom(h, 'reset');
imagesc(updated_img);
zoom(h, 'out');
This solution keeps the zoom every the user does a modification :-) however, once the user is done, he/she cannot go back to the original zoom level.
What should I do?
% Saving zoom level
xlim = get(handles.axes, 'XLim');
ylim = get(handles.axes, 'YLim');
% Displaying image
imagesc(im, 'Parent', handles.axes, 'ButtonDownFcn', #axes_ButtonDownFcn);
% Setting saved zoom level.
set(handles.axes, 'XLim', xlim);
set(handles.axes, 'YLim', ylim);
have an image that I would like to zoom in/out when I left/Right-click a point on the image but I do not want to do it using the magnifying glass. Basically, I need a script for what I said above. I have come up with the following script but it only zooms in/out to the center not to the position that I click on.
And if you are asking why I am getting the clicked position using ginput the answer is, I am planning to use this script to edit a binary image! I have removed the lines corresponding to the binary image editing part to avoid any confusion.
hFi= figure; imshow(e);
button=0;
while button~=2
% Get the mouse position on the axes (needed for binary image editing) and button number
[y,x,button]=ginput(1);
% Get the mouse position on the figure
position=get(hFi,'CurrentPoint')
% Set 'CurrentPoint' to the mouse position that was just captured
set(hFi,'CurrentPoint',position)
% Determine if it is a zoom-in or zoom-out
if button==1
zoom(2);
elseif button==3
zoom(0.5);
end
end
I think the command set() does not do anything here but I saw someone suggested that in a forum. Sorry if that looks dumb!
I am assuming you have a matrix as you are asking for the y and x values.
In this way a simple answer would be to display a smaller, or a larger range of values.
Let A be your matrix.
A=rand(1000,1000);
figure,
h=imagesc(A)
axis off
axis image
colormap('gray')
A_range=size(A);
A_zoom=1;
while true
[y,x,button]=ginput(1)
A_center=[x,y];
if button==1
A_zoom=A_zoom/2;
elseif button==3
A_zoom=A_zoom*2;
end
axis([max(x-A_range(1)*A_zoom,1), min(x+A_range(1)*A_zoom,A_range(1)), ...
max(y-A_range(2)*A_zoom,1), min(y+A_range(2)*A_zoom,A_range(2))])
end
Alright, after playing around with imshow and reading through the documentation on internet, I finally came up with what I had been looking for. Thanks to everyone who suggested some ideas, especially ASantosRibeiro who gave me the idea of changing the axis limits.
Basically, I used a combination of commands zoom and xlim/ylim. Therefore, the final code would look like:
hFi= figure; h=imshow(e);
button=0;
zlvl=1;
xl = get(gca,'xlim');
xlen = size(e,2);
yl = get(gca,'ylim');
ylen = size(e,1);
while button~=2
% Get the mouse position on the axes (needed for binary image editing) and button number
[y,x,button]=ginput(1);
% Determine if it is a zoom-in or zoom-out
if button==1
zlvl = zlvl*2;
zoom(2);
elseif button==3
zlvl = zlvl/2;
if zlvl<1, zlvl=1; end % No zoom level smaller than 1
zoom(0.5);
end
% Change the axis limits to where the mouse click has occurred
% and make sure that the display window is within the image dimensions
xlimit = [x-xlen/zlvl/2+0.5 x+xlen/zlvl/2+0.5];
if xlimit(1)<0.5, xlimit=[0.5 xlen/zlvl+0.5]; end
if xlimit(2)>0.5+xlen, xlimit=[xlen-xlen/zlvl+0.5 xlen+0.5]; end
xlim(xlimit);
ylimit = [y-ylen/zlvl/2+0.5 y+ylen/zlvl/2+0.5];
if ylimit(1)<=0.5, ylimit=[0.5 ylen/zlvl+0.5]; end
if ylimit(2)>=0.5+ylen, ylimit=[ylen-ylen/zlvl+0.5 ylen+0.5]; end
ylim(ylimit);
end
This code lets you zoom in/out when you use ginput and you need to use imshow to keep the aspect ratio of image fixed. This becomes very helpful when you need to read coordinates of image pixels and zoom in/out as well. It zooms in when the user left-clicks and zooms out when the user left-clicks. If the middle button is clicked the while loop ends. Other buttons can be added to perform desired operations. For example, I added a few lines of code to edit binary images.
I would like to know your thoughts and if there is any way to make this code more efficient.
I have a 2D plot with many data elements on it covering a extensive area. Although all the data is necessary, I am usually interested on a small element of the plot.
I would like to programmatically focus the view on that element of interest, while allowing to use the zoom tool ((-) in the GUI) to fastly go back to a wider perspective.
It is easy to use set(gca, 'xlim', [limitsXOfSmallElement]) and set(gca, 'ylim', [limitsYOfSmallElement]) to set axis limits so that the small element is in focus, but this makes impossible to use the GUI (-) zoom tool to go back to the general view without manually resetting back axis limits to original values.
My intuition is that this could be solved by controlling camera properties (CameraPosition, CameraTarget and/or CameraViewAngle), but when I apply them, posterior uses of the GUI zoom tool have weird effects on the axis, as changing its position and size on the figure.
Is there a good method for setting the fragment of the 2D canvas that is displayed in the axis?
Consider the following example:
function example_zoom
%# some plot
plot(1:10)
hAx = gca;
%# save original axis limits
setappdata(hAx, 'limits',get(gca,{'XLim','YLim'}))
%# create custom toolbar button
[X,map] = imread(fullfile(toolboxdir('matlab'),'icons','view_zoom_out.gif'));
icon = ind2rgb(X,map);
uipushtool('CData',icon, 'ClickedCallback',{#click_cb,hAx});
%# zoom
uiwait(msgbox('Zooming now, click button to reset', 'modal'))
set(gca, 'XLim',[3 7], 'YLim',[2 9])
%zoom on
end
function click_cb(o,e, hAx)
%# restore original axis limits
limits = getappdata(hAx, 'limits');
set(hAx, 'XLim',limits{1}, 'YLim',limits{2})
end
The idea is to create your own toolbar button that restores the axis limits to their original values.
I know that I can set the zoom state of a MATLAB figure using, for example, the following code:
zoom on;
zoom(2); % zoom in 2x
What I would like to achieve is to zoom in at a specific position of the figure, which I would specify as co-ordinates. How would I do this? I presume there must be some command which allows you to specify the figure pan position.
set(gca,'xlim',[minx maxx],'ylim',[miny maxy])