📄 xferplot.m
字号:
%
% NOTE: update_lines() does NOT alter/update the x-data,
% so it needs to be set up once here, correctly.
% The y-data is not significant ... just needs to be
% sized appropriately:
xLen=length(xData);
uNaN = NaN;
for i=1:length(hline),
yData = get(hline(i),'YData')';
% Manufacture the right yData if default is present:
if length(yData) ~= xLen,
yData = uNaN(ones(xLen,1));
end
set(hline(i),'XData',xData, 'YData',yData);
end
% Setup "stem" line data:
% -----------------------
% Stems are implemented as a SECOND line
% The usual data plotting occurs, but with a circle ('o')
% substituted for the marker.
% In addition, a second line is set up for the vertical
% stems themselves.
%
% We only need to set up ONE stem line.
% The vertical extent will reach to the "highest" point
% at each sample time, effectively providing a stem for
% *all* data channels at one time.
%
% Vertical stem data:
%
% [x1 x1 x1 x2 x2 x2 x3 x3 x3 ....]
% [0 y1 NaN 0 y2 NaN 0 y3 NaN ...]
xstem = [xData';xData';xData'];
xstem = xstem(:)'; % triplicate each value
ymin = 0; % stems originate from y=0, not block_data.params.YMin
ystem = [ymin;0;NaN]; % assume y values are 0 for now
ystem = ystem(:,ones(size(xData)));
ystem = ystem(:)';
set(hstem, 'xdata', xstem, 'ydata', ystem);
% Perform AxisZoom:
% -----------------
%
% Put axis into correct zoom state:
fig_data = get(hfig,'UserData');
if strcmp(block_data.params.AxisZoom,'off'),
% Turn off AxisZoom:
% - turn on menus
set(fig_data.menu.top,'vis','on');
% - reset axis position
set(hax, fig_data.main.axiszoom.off{:});
else
% Turn on AxisZoom:
% - turn off top-level menus
set(fig_data.menu.top,'vis','off');
set(hax, fig_data.main.axiszoom.on{:});
end
% Turn on scalar warning message, if appropriate:
% ------------------------------
isScalarPlot = (samples_per_channel==1) & (nframes==1);
if isScalarPlot,
if block_data.params.Domain==2,
tstr='[Plotting single points - consider using a vector input]';
else
tstr='[Plotting single points - consider increasing the display span]';
end
else
tstr='';
end
set(get(hax,'Title'), 'String', tstr, 'color','b');
% Update Frame Number display:
% ----------------------------
%
if isOn(block_data.params.FrameNumber),
% Move frame # text depending on axis zoom (on or off)
% The frame handle vector contains:
% .hframenum(1) = "Frame:"
% .hframenum(2) = "###"
% NOTE: Position of frame readout is updated in figresize
%
if isOn(block_data.params.AxisZoom),
% Axis zoom on - x-axis is not visible
ltgrayt = ones(1,3)*.6; % slightly darker for grid labels
set(block_data.hframenum, ...
'verticalalignment','bottom', ...
'color',ltgrayt, 'vis','on');
else
% Axis zoom off - x-axis is visible
set(block_data.hframenum, ...
'verticalalignment','cap', ...
'color','k', 'vis','on');
end
else
set(block_data.hframenum,'vis','off');
end
% Update line erase mode (Persistence):
startLineEraseMode(block_name);
UpdateLegend(block_name);
% Manually call the resize fcn:
FigResize([],[],hfig);
% ---------------------------------------------------------------
function UpdateLegend(blk)
block_data = get_param(blk,'UserData');
hlegend = block_data.hlegend;
useLegend = isOn(block_data.params.AxisLegend);
if ishandle(hlegend),
delete(hlegend);
end
hlegend = [];
if useLegend,
hlines = block_data.hline;
% Get signal names:
names = getInputSignalNames(blk);
% Prevent failures in legend:
prop = 'ShowHiddenHandles';
old_state = get(0,prop);
set(0,prop,'on');
axes(block_data.haxis);
hlegend = legend(hlines, names{:});
% hlegend = legend(block_data.haxis, hlines, str{:});
set(0,prop,old_state);
end
% Store changes to legend handle:
block_data.hlegend = hlegend;
set_param(blk,'UserData',block_data);
% ---------------------------------------------------------------
function UpdateFrameNumPos(blk)
block_data = get_param(blk,'UserData');
if isOn(block_data.params.FrameNumber),
if isOn(block_data.params.AxisZoom),
% Axis zoom on - x-axis is not visible
%
% Position "Frame: #" text above the x-axis tick numbers
% and to the right of the y-axis tick numbers
%
hgridtxt = block_data.hgridtext;
grid_ext = get(hgridtxt(1),'extent');
ypos = grid_ext(2)+grid_ext(4);
grid_ext = get(hgridtxt(end),'extent');
xpos = grid_ext(1)+grid_ext(3);
set(block_data.hframenum(1), ...
'units','data', 'pos',[xpos ypos]);
ex=get(block_data.hframenum(1),'extent');
set(block_data.hframenum(2), ...
'units','data', 'pos',[ex(1)+ex(3) ypos]);
else
% Axis zoom off - x-axis is visible
%
% Position "Frame: #" at the same y-level as the x-axis label
% and flush with the start of the x-axis.
hax = block_data.haxis;
hxtitle = get(hax,'xlabel');
set(hxtitle','units','data');
xtpos = get(hxtitle,'pos');
xlim = get(hax,'xlim');
set(block_data.hframenum(1), 'units','data', ...
'pos',[xlim(1) xtpos(2)]);
ex=get(block_data.hframenum(1),'extent');
frpos = [ex(1)+ex(3) xtpos(2)];
set(block_data.hframenum(2), 'units','data', ...
'pos',frpos);
% If xlabel overlaps frame label, turn off frame label:
xtitle_ex = get(hxtitle,'extent');
fr_ex = get(block_data.hframenum(2),'extent');
overlap = xtitle_ex(1) < (fr_ex(1)+fr_ex(3));
if overlap, vis='off'; else vis='on'; end
set(block_data.hframenum,'vis',vis);
end
end
% ---------------------------------------------------------------
function FigResize(hcb,eventStruct,hfig)
% Callback from window resize function
if nargin<3, hfig = gcbf; end
fig_data = get(hfig,'UserData');
if isempty(fig_data), return; end
blk = fig_data.block;
block_data = get_param(blk,'UserData');
% Resize the axis when not in "compact display" (axis zoom) mode:
if ~isOn(block_data.params.AxisZoom),
fig_pos = get(hfig,'pos');
ax_pos = [60 40 max([1 1], fig_pos([3 4])-[80 60])];
set(block_data.haxis, 'pos',ax_pos);
end
UpdateGrid(blk); % Do this prior to repositioning frame # text
UpdateFrameNumPos(blk);
% Update legend, if it is on:
if isOn(block_data.params.AxisLegend),
legend('ResizeLegend', block_data.haxis);
end
% ---------------------------------------------------------------
function fig_data = create_scope(block_name, params, nchans)
% CREATE_SCOPE Create new scope GUI
% Initialize empty settings:
fig_data.main = []; % until we move things here
fig_data.menu = [];
hfig = figure('numbertitle', 'off', ...
'name', block_name, ...
'menubar', 'none', ...
'position', params.FigPos, ...
'nextplot', 'add', ...
'integerhandle', 'off', ...
'doublebuffer', 'off', ...
'PaperPositionMode', 'auto', ...
'ResizeFcn', @FigResize, ...
'DeleteFcn', @FigDelete, ...
'HandleVisibility', 'callback');
hax = axes('Parent',hfig, ...
'DrawMode','fast', ...
'Box','on', 'ticklength',[0 0], ...
'Position', [0.1300 0.1450 0.7750 0.8000]);
% Set up line for each channel:
for i = 1:nchans,
hline(i) = line('parent',hax, ...
'xdata',NaN, 'ydata',NaN);
end
hstem = line('parent',hax, ...
'xdata',NaN, 'ydata',NaN);
hgrid = line('parent',hax, ...
'xdata',NaN, 'ydata',NaN, ...
'erasemode','xor', 'color',[.8 .8 .8]);
% Create non-displaying line to use for color translations
hcspec = line('parent',hax, ...
'xdata',nan,'ydata',nan, ...
'vis','off');
% Create Frame Number text
hframenum(1) = text(0,0,'','parent',hax);
hframenum(2) = text(0,0,'','parent',hax);
set(hframenum(1),'string','Frame: ','erase','xor','horiz','left');
set(hframenum(2),'string','-','erase','xor','userdata',0,'horiz','left');
% Create a context menu:
mContext = uicontextmenu('parent',hfig);
% Establish settings for all structure fields:
fig_data.block = block_name;
fig_data.hfig = hfig;
fig_data.hcspec = hcspec;
% Store major settings:
fig_data.main.haxis = hax;
fig_data.main.hline = hline;
fig_data.main.hstem = hstem;
fig_data.main.hgrid = hgrid;
fig_data.main.hframenum = hframenum;
fig_data.menu.context = mContext;
% Set the non-compact display axis to pixels,
% so resizing does not affect it
set(hax,'units','pixels')
% Store settings for axis zoom:
% Cell-array contains {params, values},
% where params itself is a cell-array of Units and Position
% and values is a cell-array of corresponding values.
p = {'Units','Position'};
fig_data.main.axiszoom.off = {p, get(hax, p)};
fig_data.main.axiszoom.on = {p, {'Normalized',[0 0 1 1]}};
% ---------------------------------------------------------
% Figure menus:
% ---------------------------------------------------------
%
% Define FILE menu:
%
pcwin = strcmp(computer,'PCWIN');
if pcwin,
labels = {'&File', ...
'&Close', ...
'&Export...', ...
'Pa&ge Setup...', ...
'Print Set&up...', ...
'Print Pre&view...', ...
'&Print...'};
else
labels = {'File', ...
'Close', ...
'Export...', ...
'Page Setup...', ...
'Print Setup...', ...
'Print Preview...', ...
'Print...'};
end
%
mFile = uimenu(hfig,'Label',labels{1});
%
% submenu items:
uimenu(mFile, 'label',labels{2}, ...
'accel','W', ...
'callback',{@CloseFigure, block_name});
%uimenu(mFile, 'label',labels{3}, ...
% 'separator','on', ...
% 'callback','filemenufcn(gcbf,''FileExport'')');
uimenu(mFile, 'label',labels{4}, ...
'separator','on', ...
'callback','pagesetupdlg(gcbf)');
uimenu(mFile, 'label',labels{5}, ...
'callback','printdlg(''-setup'')');
uimenu(mFile, 'label',labels{6}, ...
'callback','printpreview(gcbf)');
uimenu(mFile, 'label',labels{7}, ...
'accel','P', ...
'callback','printdlg(gcbf)');
%
% Define AXES menu labels:
%
if pcwin,
labels = {'&Axes', 'Per&sistence', '&Refresh', ...
'&Autoscale', 'Show &grid', 'Compact &display', ...
'&Frame #', 'Channel &legend', 'Save &position'};
else
labels = {'Axes', 'Persistence', 'Refresh', ...
'Autoscale', 'Show grid', 'Compact display', ...
'Frame #', 'Channel legend', 'Save position'};
end
%
% Create figure AXIS menu
%
mAxes = uimenu(hfig, 'Label', labels{1}); % top-level Axes menu in figure
%
% submenu items:
fig_data.menu.memory = uimenu(mAxes, 'label',labels{2}, ...
'callback',@Memory);
fig_data.menu.refresh = uimenu(mAxes, 'label',labels{3}, ...
'callback',@FigRefresh);
fig_data.menu.autoscale = uimenu(mAxes, 'label',labels{4}, ...
'separator','on', 'callback', @Autoscale);
% - Create Axis Grid item
fig_data.menu.axisgrid = uimenu(mAxes, 'Label', labels{5}, ...
'Callback', @AxisGrid);
% - Create Axis Zoom item
fig_data.menu.axiszoom = uimenu(mAxes, ...
'Label', labels{6}, ...
'Callback', @AxisZoom);
% - Create Axis Frame Number item
fig_data.menu.framenumber = uimenu(mAxes, 'Label', labels{7}, ...
'Callback', @FrameNumber);
% - Create Axis Legend item
fig_data.menu.axislegend = uimenu(mAxes, 'Label', labels{8}, ...
'Callback', @AxisLegend);
% - Create Record Position item
fig_data.menu.recpos = uimenu(mAxes, 'label',labels{9}, ...
'callback', @SaveFigPos, ...
'separator','on');
% Define OPTIONS menu labels:
%
if pcwin,
% Use "&" for accelerator characters on the PC:
labels = {'&Channels', '&Style', '&Marker', '&Color'};
else
labels = {'Channels', 'Style', 'Marker', 'Color'};
end
%
% Create menus as if there were only ONE line in display:
if nchans >= 1,
mLines = uimenu(hfig, 'label',labels{1}); % top-level Lines menu in figure
lsmenu = uimenu(mLines, 'label',labels{2});
lmmenu = uimenu(mLines, 'label',labels{3});
lcmenu = uimenu(mLines, 'label',labels{4});
fig_data.menu.linestyle = lsmenu;
fig_data.menu.linemarker = lmmenu;
fig_data.menu.linecolor = lcmenu;
% Line styles submenu:
uimenu(lsmenu,'label',' None', 'userdata','None', ...
'callback',@LineStyle);
uimenu(lsmenu,'label',' -', 'userdata','-', ...
'callback',@LineStyle);
uimenu(lsmenu,'label',' --', 'userdata','--', ...
'callback',@LineStyle);
uimenu(lsmenu,'label',' :', 'userdata',':', ...
'callback',@LineStyle);
uimenu(lsmenu,'label',' -.', 'userdata','-.', ...
'callback',@LineStyle);
% Line markers submenu:
uimenu(lmmenu,'label','None','userdata','None', ...
'callback',@LineMarker);
uimenu(lmmenu,'label','+','userdata','+',...
'callback',@LineMarker);
uimenu(lmmenu,'label','o','userdata','o',...
'callback',@LineMarker);
uimenu(lmmenu,'label','*','userdata','*',...
'callback',@LineMarker);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -