📄 linkedzoom.m
字号:
state = uiclearmode(fig1,'docontext',h,fig,'off');
% restore button down functions for uicontrol children of the figure
uirestore(state,'uicontrols');
setappdata(fig1,'ZOOMFigureState',state);
end
% We use handles to function so that we can use this mfile as a local function
%
h=@linkedzoom;
set(fig,'windowbuttondownfcn',{h,hAxes,'down'}, ...
'windowbuttonupfcn','ones;', ...
'windowbuttonmotionfcn','','buttondownfcn','',...
'interruptible','on');
set(ax,'interruptible','on')
% set an appdata so it will always be possible to
% determine whether or not zoom is on and in what
% type of 'on' stat it is.
% this appdata will not exist when zoom is off
setappdata(fig1,'ZoomOnState','on');
% if isappdata(fig1,'ZOOMAxesHandles');
% hAxes = getappdata(fig1,'ZOOMAxesHandles');
% else
% hAxes = [];
% end;
% if isempty(hAxes)
% hchildren = get(fig,'Children');
% for c= 1:length(hchildren)
% if strcmp('axes',get(hchildren(c),'Type'))
% hAxes = [hAxes,hchildren(c)];
% end;
% end
% setappdata(fig1,'ZOOMAxesHandles',hAxes);
% end;
linkedzoom(hAxes,'setlimits');
return
case 'out',
limits = linkedzoom(hAxes,'getlimits');
center = [sum(localget_xlim(ax))/2 sum(localget_ylim(ax))/2];
m = -inf; % Zoom totally out
case 'clear',
for c= 1:length(hAxes)
if isappdata(get(hAxes(c),'ZLabel'),'ZOOMAxesData')
rmappdata(get(hAxes(c),'ZLabel'),'ZOOMAxesData')
end;
end
return;
case 'setlimits',
state = getappdata(fig1,'ZOOMFigureState');
for c= 1:length(hAxes)
axes(hAxes(c));
% Limits is stored in appdata so no need to store it again,
% but it is returned anyway.
limits = linkedzoom(hAxes,'getlimits');
end;
return;
case 'getlimits', % Get axis limits
axz = get(ax,'ZLabel');
limits = getappdata(axz,'ZOOMAxesData');
% Do simple checking of userdata
if size(limits,2)==4 & size(limits,1)<=2,
if all(limits(1,[1 3])<limits(1,[2 4])),
getlimits = 0; out = limits(1,:);
return % Quick return
else
getlimits = -1; % Don't munge data
end
else
if isempty(limits)
getlimits = 1;
else
getlimits = -1;
end
end
% If I've made it to here, we need to compute appropriate axis
% limits.
if isempty(getappdata(axz,'ZOOMAxesData')),
% Use quick method if possible
xlim = localget_xlim(ax); xmin = xlim(1); xmax = xlim(2);
ylim = localget_ylim(ax); ymin = ylim(1); ymax = ylim(2);
elseif strcmp(get(ax,'xLimMode'),'auto') & ...
strcmp(get(ax,'yLimMode'),'auto'),
% Use automatic limits if possible
xlim = localget_xlim(ax); xmin = xlim(1); xmax = xlim(2);
ylim = localget_ylim(ax); ymin = ylim(1); ymax = ylim(2);
else
% Use slow method only if someone else is using the userdata
h = get(ax,'Children');
xmin = inf; xmax = -inf; ymin = inf; ymax = -inf;
for i=1:length(h),
t = get(h(i),'Type');
if ~strcmp(t,'text'),
if strcmp(t,'image'), % Determine axis limits for image
x = get(h(i),'Xdata'); y = get(h(i),'Ydata');
x = [min(min(x)) max(max(x))];
y = [min(min(y)) max(max(y))];
[ma,na] = size(get(h(i),'Cdata'));
if na>1
dx = diff(x)/(na-1);
else
dx = 1;
end
if ma>1
dy = diff(y)/(ma-1);
else
dy = 1;
end
x = x + [-dx dx]/2; y = y + [-dy dy]/2;
end
xmin = min(xmin,min(min(x)));
xmax = max(xmax,max(max(x)));
ymin = min(ymin,min(min(y)));
ymax = max(ymax,max(max(y)));
end
end
% Use automatic limits if in use (override previous calculation)
if strcmp(get(ax,'xLimMode'),'auto'),
xlim = localget_xlim(ax); xmin = xlim(1); xmax = xlim(2);
end
if strcmp(get(ax,'yLimMode'),'auto'),
ylim = localget_ylim(ax); ymin = ylim(1); ymax = ylim(2);
end
end
limits = [xmin xmax ymin ymax];
if getlimits~=-1, % Don't munge existing data.
% Store limits ZOOMAxesData
% store it with the ZLabel, so that it's cleared if the
% user plots again into this axis. If that happens, this
% state is cleared
axz = get(ax,'ZLabel');
setappdata(axz,'ZOOMAxesData',limits);
end
out = limits;
return
otherwise
errordlg(['Unknown option: ',zoomCommand,'.']);
end
%
% Actual zoom operation
%
if ~rbbox_mode,
xmin = limits(1); xmax = limits(2);
ymin = limits(3); ymax = limits(4);
if m==(-inf),
dx = xmax-xmin;
dy = ymax-ymin;
else
dx = diff(localget_xlim(ax))*(scale_factor.^(-m-1)); dx = min(dx,xmax-xmin);
dy = diff(localget_ylim(ax))*(scale_factor.^(-m-1)); dy = min(dy,ymax-ymin);
end
% Limit zoom.
center = max(center,[xmin ymin] + [dx dy]);
center = min(center,[xmax ymax] - [dx dy]);
a = [max(xmin,center(1)-dx) min(xmax,center(1)+dx) ...
max(ymin,center(2)-dy) min(ymax,center(2)+dy)];
% Check for log axes and return to linear values.
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
end
% Check for axis equal and update a as necessary
if strcmp(get(ax,'plotboxaspectratiomode'),'manual') & ...
strcmp(get(ax,'dataaspectratiomode'),'manual')
ratio = get(ax,'plotboxaspectratio')./get(ax,'dataaspectratio');
dx = a(2)-a(1);
dy = a(4)-a(3);
[kmax,k] = max([dx dy]./ratio(1:2));
if k==1
dy = kmax*ratio(2);
a(3:4) = mean(a(3:4))+[-dy dy]/2;
else
dx = kmax*ratio(1);
a(1:2) = mean(a(1:2))+[-dx dx]/2;
end
end
% Update circular list of connected axes
% This is the key to the linked xzoom.
mode = getappdata(fig1,'ZOOMMode');
for c= 1:length(hAxes)
axz = get(hAxes(c),'ZLabel');
if ~isappdata(axz,'ZOOMAxesData');
% If limit is not save yet save it before setting new axes
fig_temp = get(hAxes(c),'Parent');
set(fig,'currentaxes',hAxes(c));
limit = linkedzoom(hAxes,'getlimits');
end;
switch mode
case 'onx'
set(hAxes(c),'xlim',a(1:2));
case 'ony'
set(hAxes(c),'ylim',a(3:4));
case 'onxy'
set(hAxes(c),'xlim',a(1:2));
set(hAxes(c),'ylim',a(3:4));
case 'onx2'
set(hAxes(c),'xlim',a(1:2));
if (hAxes(c)==ax)
set(hAxes(c),'ylim',a(3:4));
end;
case 'ony2'
set(hAxes(c),'ylim',a(3:4));
if (hAxes(c)==ax)
set(hAxes(c),'xlim',a(1:2));
end;
otherwise
set(hAxes(c),'xlim',a(1:2));
set(hAxes(c),'ylim',a(3:4));
end;
end;
%
% zoom Helper Functions
%
% --------------------------------------------------------------------
% zoom Helper Functions
function p = localget_currentpoint(ax)
%GET_CURRENTPOINT Return equivalent linear scale current point
p = get(ax,'currentpoint'); p = p(1,1:2);
if strcmp(get(ax,'XScale'),'log'),
p(1) = log10(p(1));
end
if strcmp(get(ax,'YScale'),'log'),
p(2) = log10(p(2));
end
% --------------------------------------------------------------------
% zoom Helper Functions
function xlim = localget_xlim(ax)
%GET_XLIM Return equivalent linear scale xlim
xlim = get(ax,'xlim');
if strcmp(get(ax,'XScale'),'log'),
xlim = log10(xlim);
end
% --------------------------------------------------------------------
% zoom Helper Functions
function ylim = localget_ylim(ax)
%GET_YLIM Return equivalent linear scale ylim
ylim = get(ax,'ylim');
if strcmp(get(ax,'YScale'),'log'),
ylim = log10(ylim);
end
% --------------------------------------------------------------------
% input checking function
function [fig,hAxes] = localcheck_handle_input(fig)
%See if input was a figure or a vector of axes handles
InputType = get(fig,'Type');
if ~iscell(InputType); InputType = {InputType}; end;
if ~(strcmp(InputType{1},'figure') | strcmp(InputType{1},'axes'))
errordlg('First Argument must be a valid Figure or Axes handle.');
return;
end;
%Require all elements to be the same type (figure or axes)
if prod(double(strcmp('figure',InputType))); %All figures
hAxes = findobj(fig,'Type','Axes');
elseif prod(double(strcmp('axes',InputType))); %All axes
hAxes = fig;
fig = get(hAxes,'Parent');
[junk,ndx] =unique([fig{:}]); %Convert to array
fig = [fig{sort(ndx)}];
else
error('Must specify EITHER figures OR axes');
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -