第一步:在原始工程文件的最后添加以下语句
% add a zoomed zone
zp = BaseZoom();
zp.plot;
第二步:在原始工程目录下添加以下两个文件
文件名:BaseZoom.m
代码如下:
classdef BaseZoom < handle
% main properties
properties
subFigure
mainAxes
subAxes
roi
zoomedArea
param
XAxis
YAxis
direction
% image-related properties
uPixels
vPixels
vuRatio
CData_
Colormap_
imageDim
imagePosition = [0.1, 0.1, 0.8, 0.6]
imageRectangleEdgePosition
imageArrow
% figure-related properties
mappingParams
figureRectangleEdgePosition
lineDirection
axesPosition
figureArrow
% others
drawFunc
axesClass
axesDone = 'off'
rectangleDone = 'off'
pauseTime = 0.2
textDisplay = 'on'
end
% dynamic properties
properties(Dependent)
XLimNew
YLimNew
affinePosition
dynamicPosition
newCData_
newCData
newCMap
end
methods
function plot(this)
% main steps
this.checkVersion;
this.initialize;
this.loadParameters;
switch this.axesClass
case 'image'
this.addSubAxes;
this.axesDone = 'off';
fprintf('Use the left mouse button to draw a rectangle.\n')
fprintf('for the zoomed area...\n')
this.addZoomedArea;
this.rectangleDone = 'off';
case 'figure'
fprintf('Use the left mouse botton to draw a rectangle.\n')
fprintf('for the sub axes...\n')
this.addSubAxes;
this.axesDone = 'off';
fprintf('Use the left mouse button to draw a rectangle.\n')
fprintf('for the zoomed area...\n')
this.addZoomedArea;
this.rectangleDone = 'off';
end
end
function checkVersion(this)
version_ = version('-release');
year_ = str2double(version_(1:4));
if year_ < 2016
error('ZoomPlot V1.4 is not compatible with the versions lower than R2016a.')
end
if year_ >= 2017
set(findobj(gcf, 'type', 'Legend'), 'AutoUpdate', 'off');
end
if year_ > 2018 || (year_ == 2018 && version_(5) == 'b')
this.drawFunc = 'drawrectangle';
else
this.drawFunc = 'imrect';
end
end
function loadParameters(this)
fileName = 'parameters.json';
fid = fopen(fileName);
raw = fread(fid,inf);
str = char(raw');
fclose(fid);
this.param = jsondecode(str);
names_ = fieldnames(this.param);
for i = 1:length(names_)
if isfield(this.param.(names_{i}), 'Comments')
this.param.(names_{i}) = rmfield(this.param.(names_{i}), 'Comments');
end
end
end
function initialize(this)
this.mainAxes = gca;
this.YAxis.direction = {'left', 'right'};
this.YAxis.number = length(this.mainAxes.YAxis);
this.XAxis.number = length(this.mainAxes.XAxis);
this.XAxis.scale = this.mainAxes.XScale;
this.direction = this.mainAxes.YAxisLocation;
switch this.YAxis.number
case 1
this.YAxis.(this.direction).scale = this.mainAxes.YScale;
case 2
for i = 1:2
yyaxis(this.mainAxes, this.YAxis.direction{1, i});
this.YAxis.(this.YAxis.direction{1, i}).scale = this.mainAxes.YScale;
this.YAxis.scale{i} = this.mainAxes.YScale;
end
this.YAxis.scale = cell2mat(this.YAxis.scale);
yyaxis(this.mainAxes, this.direction);
end
if size(imhandles(this.mainAxes),1) ~= 0
this.axesClass = 'image';
this.CData_ = get(this.mainAxes.Children, 'CData');
this.Colormap_ = colormap(gca);
if size(this.Colormap_, 1) == 64
this.Colormap_ = colormap(gcf);
end
[this.vPixels, this.uPixels, ~] = size(this.CData_);
this.vuRatio = this.vPixels/this.uPixels;
this.imageDim = length(size(this.CData_));
else
this.axesClass = 'figure';
end
end
function addSubAxes(this)
switch this.axesClass
case 'image'
this.subFigure = figure;
this.imagePosition(4) = this.imagePosition(3)*this.vuRatio;
set(this.subFigure, 'Units', 'Normalized', 'OuterPosition', this.imagePosition);
subplot(1, 2, 1, 'Parent', this.subFigure);
image(this.CData_);
this.mainAxes = gca;
if this.imageDim == 2
colormap(this.mainAxes, this.Colormap_);
end
axis off
subplot(1, 2, 2, 'Parent', this.subFigure);
image((ones(this.vPixels, this.uPixels)));
this.subAxes = gca;
colormap(this.subAxes, [240, 240, 240]/255);
axis off
case 'figure' %
switch this.drawFunc
case 'drawrectangle'
this.roi = drawrectangle(this.mainAxes);
this.setTheme;
this.creatSubAxes;
set(gcf, 'WindowButtonDownFcn', {@this.clickEvents, 'subAxes'});
addlistener(this.roi, 'MovingROI', @(source, event) ...
this.allEvents(source, event, 'subAxes'));
addlistener(this.roi, 'ROIMoved', @(source, event) ...
this.allEvents(source, event, 'subAxes'));
while strcmp(this.axesDone, 'off')
pause(this.pauseTime);
end
case 'imrect'
this.roi = imrect;
this.setTheme;
func_ = makeConstrainToRectFcn('imrect',...
get(this.mainAxes, 'XLim'), get(this.mainAxes, 'YLim'));
setPositionConstraintFcn(this.roi, func_);
this.creatSubAxes;
addNewPositionCallback(this.roi, @(handle) ...
allEvents(this, this.roi, [], 'subAxes'));
set(gcf, 'WindowButtonDownFcn', {@this.clickEvents, 'subAxes'});
wait(this.roi);
while strcmp(this.axesDone, 'off')
pause(this.pauseTime);
end
end
end
end
function addZoomedArea(this)
switch this.axesClass
case 'image'
switch this.drawFunc
case 'drawrectangle'
this.roi = drawrectangle(this.mainAxes);
this.setTheme;
this.creatSubAxes;
if strcmp(this.param.subAxes.Box, 'on')
this.connectAxesAndBox;