📄 linkedzoom.m
字号:
function out = linkedzoom(varargin)
% linkedzoom: link zooming on all subplots of current figure.
% This function give users the ability to zoom in a given direction
% and will force all the subplots of the figure to have the same axis.
%
% Usage:
% linkedzoom -> Toggles linkedzoom on current figure using default zoom of both x and y.
% linkedzoom(fig,'ZoomCommand'), where fig is a figure handle applies ZoomCommand to all axes in fig
% linkedzoom(h,'ZoomCommand'), where h is a vector of axes handles applies ZoomCommand to specified axes
% ZoomCommand->
% off Turns off linkedzoom
% onx link x axis of all subplots of specified fig, leave y axis unmodified
% ony link y axis of all subplots of specified fig, leave x axis unmodified
% onxy link x and y axis of all subplots of specified fig
% onx2 link x axis of all subplots of specified fig, zoom y axis of gca only
% ony2 link y axis of all subplots of specified fig, zoom x axis of gca only
%
% linkedzoom ZoomCommand applies ZoomCommand to the current figure
%
% A few limitations:
% Double clicking to restore axis limits doesn't work quite as you
% might expect. It sets all axes to the limits of the current axes,
% not to their original values.
% If you initiate linkedzoom with a handle input, you must
% continue to use that handle input for subsequent calls.
% e.q. linkedzoom(h,'onx'); linkedzoom off
% is not a good idea
% Internal functions calling us again use the following:
%
% down linkedzoom is zooming in
% out linkedzoom is zooming out
% clear linkedzoom is clearing limits of axes
% setlimit linkedzoom is setting the limits of axes based on current axes
% getlimit linkedzoom returns current limits for current axes.
%
% linkedzoom(fig,[],'ZoomCommand'); % Called from Figure.
%
out=[];
switch nargin
case 0
fig = gcf;
hAxes = findobj(fig,'Type','Axes');
if isappdata(fig,'ZOOMFigureState')
zoomCommand = 'off';
else
zoomCommand = 'onxy';
end;
case 1
if ischar(varargin{1})
fig = gcf;
hAxes = findobj(fig,'Type','Axes');
zoomCommand = varargin{1};
else
fig = varargin{1};
%Get handles to all involved figures and axes
try
[fig,hAxes] = localcheck_handle_input(fig);
catch
error(lasterr);
end;
if isappdata(fig,'ZOOMFigureState')
zoomCommand = 'off';
else
zoomCommand = 'onxy';
end;
end;
case 2
fig = varargin{1};
%Get handles to all involved figures and axes
try
[fig,hAxes] = localcheck_handle_input(fig);
catch
error(lasterr);
end;
zoomCommand = lower(varargin{2});
% case 3
% fig = varargin{1};
% %Get handles to all involved figures and axes
% try
% [fig,hAxes] = localcheck_handle_input(fig);
% catch
% error(lasterr);
% end;
%
% zoomCommand = lower(varargin{3});
case 4
hAxes = varargin{3};
fig = get(hAxes,'Parent');
[junk,ndx] =unique([fig{:}]); %Convert to array
fig = [fig{sort(ndx)}];
%Get handles to all involved figures and axes
zoomCommand = lower(varargin{4});
otherwise
errordlg('Unknown arguments sent to linkedzoom.');
end;
if (length(hAxes)==1)
warning('Must have multiple plots to use linked zoom');
linkedzoom(fig,'off');
return;
end;
fig1 = fig(1); %Use this for appdata
switch zoomCommand % special cases of zoomCommand ON so remember them and just use on
case {'onx','ony','onxy','onx2','ony2'}
setappdata(fig1,'ZOOMMode',zoomCommand);
zoomCommand = 'on';
end;
%
% set some things we need for zoomCommands
%
if ismember(gcf,fig)
ax=get(gcf,'currentaxes');
else
ax = get(fig1,'currentaxes');
end;
if ~ismember(ax,hAxes)
return
end;
% if isappdata(fig1,'ZOOMAxesHandles');
% hAxes = getappdata(fig1,'ZOOMAxesHandles');
% else
% hAxes = [];
% end;
rbbox_mode = 0;
%
% Switch on zoomCommand
%
switch zoomCommand
case 'off'
% turn zoom off
state = getappdata(fig1,'ZOOMFigureState');
if ~isempty(state)
% since we didn't set the pointer,
% make sure it does not get reset
ptr = get(fig1,'pointer');
% restore figure and non-uicontrol children
% don't restore uicontrols because they were restored
% already when zoom was turned on
uirestore(state,'nouicontrols');
set(fig1,'pointer',ptr)
% Remove all appdata we set
if isappdata(fig1,'ZOOMFigureState')
rmappdata(fig1,'ZOOMFigureState');
end
% get rid of on state appdata if it exists
% the non-existance of this appdata
% indicates that zoom is off.
if isappdata(fig1,'ZoomOnState')
rmappdata(fig1,'ZoomOnState');
end
% if isappdata(fig1,'ZOOMAxesHandles');
%hAxes = getappdata(fig1,'ZOOMAxesHandles');
for c= 1:length(hAxes)
if isappdata(get(hAxes(c),'ZLabel'),'ZOOMAxesData')
rmappdata(get(hAxes(c),'ZLabel'),'ZOOMAxesData')
end;
end
% rmappdata(fig1,'ZOOMAxesHandles');
% end;
if isappdata(fig1,'ZOOMMode');
rmappdata(fig1,'ZOOMMode');
end;
%Sloppy cleanup, to get any figures without appdata
set(fig,'windowbuttondownfcn','', ...
'windowbuttonupfcn','', ...
'windowbuttonmotionfcn','');
end
% done, go home.
return
case 'down'
% Activate axis that is clicked in
allAxes = hAxes;
ZOOM_found = 0;
% this test may be causing failures for 3d axes
for i=1:length(allAxes)
ax=allAxes(i);
ZOOM_Pt1 = get(ax,'CurrentPoint');
xlim = get(ax,'xlim');
ylim = get(ax,'ylim');
if (xlim(1) <= ZOOM_Pt1(1,1) & ZOOM_Pt1(1,1) <= xlim(2) & ...
ylim(1) <= ZOOM_Pt1(1,2) & ZOOM_Pt1(1,2) <= ylim(2))
ZOOM_found = 1;
fig_temp = get(ax,'Parent');
set(fig_temp,'currentaxes',ax);
break
end
end
if ZOOM_found==0
return
end
% Check for selection type
selection_type = get(gcf,'SelectionType');
zoomMode = getappdata(fig1,'ZOOMFigureMode');
if isempty(zoomMode) | strcmp(zoomMode,'in');
switch selection_type
case 'normal'
% Zoom in
m = 1;
scale_factor = 2; % the default zooming factor
case 'open'
% Zoom all the way out
linkedzoom(hAxes,'out');
return;
otherwise
% Zoom partially out
m = -1;
scale_factor = 2;
end
elseif strcmp(zoomMode,'out')
switch selection_type
case 'normal'
% Zoom partially out
m = -1;
scale_factor = 2;
case 'open'
% Zoom all the way out
linkedzoom(hAxes,'out');
return;
otherwise
% Zoom in
m = 1;
scale_factor = 2; % the default zooming factor
end
else % unrecognized zoomMode
return
end
ZOOM_Pt1 = localget_currentpoint(ax);
ZOOM_Pt2 = ZOOM_Pt1;
center = ZOOM_Pt1;
if (m == 1)
% Zoom in
units = char(get(fig,'units'));units = units(1,:); %Keep first value
set(fig,'units','pixels')
rbbox([get(gcf,'currentpoint') 0 0],get(gcf,'currentpoint'),gcf);
ZOOM_Pt2 = localget_currentpoint(ax);
set(fig,'units',units)
% Note the currentpoint is set by having a non-trivial up function.
if min(abs(ZOOM_Pt1-ZOOM_Pt2)) >= ...
min(.01*[diff(localget_xlim(ax)) diff(localget_ylim(ax))]),
% determine axis from rbbox
a = [ZOOM_Pt1;ZOOM_Pt2]; a = [min(a);max(a)];
% Undo the effect of localget_currentpoint for log axes
if strcmp(get(ax,'XScale'),'log'),
a(1:2) = 10.^a(1:2);
end
if strcmp(get(ax,'YScale'),'log'),
a(3:4) = 10.^a(3:4);
end
rbbox_mode = 1;
end
end
% Limits is stored in appdata so no need to store it again,
% but it is returned anyway.
limits = linkedzoom(hAxes,'getlimits');
case 'on',
state = getappdata(fig1,'ZOOMFigureState');
if isempty(state),
% turn off all other interactive modes
h=@linkedzoom;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -