|
Here is an example of what I described above.
function h = sweeping_display_nxImages_multiPanels
% This is an example of a sweeping display that can be "hidden" by changing
% the state of a togglebutton.
%
% The sweeping display is an axes with nx vertical lines (image handle
% graphics objects). The vertical lines are updated as the sweep bar
% passes across the display. The nx vertical lines can be updated
% indepdently, and only two are updated on each step of the sweep. This
% reduces the rendering performance compared to updating two columns of
% the CData of a single image object, which causes all the data in the axes
% to be refreshed.
% The problem with this example is that the image object are drawn even
% when the visible property of their parent uipanel is 'off', when their
% EraseMode = 'none'. Setting the EraseMode = 'normal' fixes this problem,
% but the image renders more slowly and flickers.
IMAGE_ERASEMODE = 'none';
RENDERER = 'painters';
%% --- display parameters
% Each 'line' is actually an image handle object of width dx
displayon = 1; % ON=1
sweeptime = 4; % time to sweep across spectral display (s)
Fdisp = 60; % number of lines displayed per second (Hz)
nx = round(Fdisp*sweeptime); % number of lines in the display
dx = 2; % width of line
ny = 128; % number of points in the Y-direction
nframes = 5; % number of times the display sweeps through
% pixelsperline = 1; % display size across screen, per displayed line
%% --- Initialize the sweeping display window
Tdisp = 1/Fdisp;
% generate axes vectors of time points representing fast- and slow-time points
X = (0:nx)*Tdisp; % times for each displayed line, on x-axis of display
Y = 1:ny;
%specimage = zeros(ny, nx); % initialize display image matrix
specimage = repmat(ceil((1:dx*nx)/dx), [ny 1]); %each vertical line is a unique index into the colormap
zerosline = zeros(ny, dx);
onesline = ones(ny, dx);
% Initialize display figure
h.figure = figure;
set(h.figure, 'ColorMap', colormap(gray(2)), ... %colormap(gray(nx)), ...
'DoubleBuffer', 'on', ...
'Renderer', RENDERER);
h.uipanel1 = uipanel('Parent', h.figure, ...
'Position', [0 0.05 1 0.95], ...
'Visible', 'on');
h.uipanel2 = uipanel('Parent', h.figure, ...
'Position', [0 0.05 1 0.95], ...
'Visible', 'off');
h.togglebutton = uicontrol('Parent', h.figure, ...
'Units', 'normalized', ...
'Style', 'togglebutton', ...
'Value', 0, ...
'String', 'Hide Sweeping Display', ...
'Position', [0 0 0.20 0.05]);
% Initialize display axes
CLim = [1 nx]; %index directly into colormap
h.axes = axes('Parent', h.uipanel1, ... %'Units', 'pixels', ...
'CLim', CLim, ...
'XLim', [X(1) X(end)], ...
'YLim', [Y(1) Y(end)], ...
'XTickLabel', {''}, ...
'YTickLabel', {''});
% Position = get(h.axes, 'Position'); %set axes size = size(CData) for direct pixel mapping
% Position(3:4) = [nx ny];
% set(h.axes, 'Position', Position);
title (['Sweeping Diplay --- [nx ny Fdisp] ' num2str([nx ny Fdisp])])
xlabel('Time (s)')
ylabel('Number of points')
colorbar;
% Initialize image lines
h.image = nan(nx, 1);
for i=1:nx
h.image(i) = image('XData', X(i:i+1), ...
'YData', Y, ...
'CData', specimage(:,i*dx-1:i*dx), ...
'CDataMapping', 'direct', ...
'Parent', h.axes, ...
'EraseMode', IMAGE_ERASEMODE, ...
'BusyAction', 'cancel');
end
set(h.togglebutton, 'Callback', {@togglePanels_Callback, h});
drawnow;
%% Display loop
iline = dx-1;
Delay = nan(nframes*nx,1);
for frame = 1:nframes
% disp ([' *** Frame ' num2str(frame) ])
tic
for nn = 1:nx % line loop
iline0 = mod(iline,dx*nx)+1; % current display line, with wrap around
iline1 = mod(iline-dx,dx*nx)+1; % next line (current +1)
% iline2 = mod(iline+1,nx)+1; % current+2
% iline3 = mod(iline+2,nx)+1; % current+3
% iline0 = mod(iline-2,nx)+1; % previous line (current-1)
% add the lines to the display
specimage(:,iline0-dx+1:iline0) = CLim(2)*onesline;
specimage(:,iline1-dx+1:iline1) = zerosline; % position bar
% specimage(:,iline2:iline2+1) = 0.5*onesline; % dimming ahead
% specimage(:,iline3:iline3+1) = 0.3*onesline;
%set(h,'CData',specimage) % write to display
set(h.image(iline0/dx), 'CData', specimage(:,iline0-dx+1:iline0));
set(h.image(iline1/dx), 'CData', specimage(:,iline1-dx+1:iline1));
% set(h.image(iline2), 'CData', specimage(:,iline2:iline2+1));
% set(h.image(iline3), 'CData', specimage(:,iline3:iline3+1));
k = (frame-1)*nx+nn;
Delay(k) = nn*Tdisp-toc; % if display is faster than the desired rate, wait
if Delay(k)>0.001,
pause(Delay(k)),
% disp ([ num2str(Delay)] );
end
% disp([' Delay = ' num2str(Delay) ' Frame = ' num2str(frame) ' Line = ' num2str(iline) ])
iline = iline + dx; % iline indexes the current line in the sweeping display
end
end
%% end Frame Loop
figure;
subplot(3,1,1);
t = (1:nframes*nx)/Fdisp;
plot(t, Delay);
title('Time series of Delay');
subplot(3,1,2);
hist(Delay);
title('Histogram of Delay');
subplot(3,1,3);
plot(t, cumsum(Delay));
title('Cumulative sum of time series of Delay');
fprintf(1, 'Mean Delay is %.4f\n', mean(Delay));
function togglePanels_Callback(hObject, eventdata, h)
if get(hObject, 'Value')
set(h.uipanel1, 'Visible', 'off');
set(h.uipanel2, 'Visible', 'on');
else
set(h.uipanel1, 'Visible', 'on');
set(h.uipanel2, 'Visible', 'off');
end
% [EOF]
|