CLA to Clear Out Axes Not Working in Slider Callback Function

1 view (last 30 days)
Hello Everyone!
I am developing an app to process and analyze vasodilation data and I have spent several days trying to fix the following two issues. Your help will be appreciated.
1) I am using a slider to go from one frame of the dataset to another. The slider updates all the graphs shown in the screenshot below. At first, the app updates the graphs pretty fast but the more I use the slider to update the graphs, the slower the app gets. I think that this is happening because the graphs are not cleared out before they are updated by the slider. You can see that this on the top graph in the screenshot below. The red markers of previously displayed graphs (highlighted with magenta) are not cleared out after choosing a different frame. I have tried to use cla in the callback function before plotting the new graphs but this does not work. Any insights about what I can do to clear out the graphs before plotting the new ones with the slider?
2) The second issue is a minor one but I would like to get it fixed. Every time I use the slider to go from one frame to another, the colorbar and the x and y titles of the graph on the left are shown on the left lower corner of the screen before being properly shown in the right place (See what is highlighted with magenta in the screenshot below) How can I fix this?
If you need to see my script, let me know. I am more than happy to share it or share parts of it. Thank you so much for your attention!
  2 Comments
Cris LaPierre
Cris LaPierre on 17 Jun 2023
How are you clearing your axes? Yes, please share your code. It is much easier to help if we can see what you are doing.
Miguel
Miguel on 17 Jun 2023
Edited: Miguel on 17 Jun 2023
Thanks for your resply Cris. I highly appreciate it. The following are snippets of the main two scripts I am using.
I load and process all the data used/shown in the app before running the following part of the script.
% MAIN SCRIPT
% APPLICATION LAYOUT
% Main Application Layout
fig = uifigure('Position',[20 200 1750 1000]);
grid = uigridlayout(fig);
grid.RowHeight = {30, '1x', '1x', '1x', 30, 35};
grid.ColumnWidth = {'1x', '1x', '1x', '1x'};
% Creating the slider and assigning its values to the getperfusiondata
slider = uislider(grid,'ValueChangedFcn',@(slider,event) changeslice_v2(slider, grid, nFrameApplOfStim, perfusionImgsVolume, flareBoundariesVolume, nFrames, flareMeanIntensities, flareAreas_mm));
% Perfusion Images Titles
perfusionImgtitle = uilabel(grid,'Text','Perfusion');
perfusionImgtitle.HorizontalAlignment = 'center';
perfusionImgtitle.FontSize = 22;
perfusionImgtitle.FontWeight = 'bold';
perfusionImgtitle.Layout.Row = 1;
perfusionImgtitle.Layout.Column = 1;
% Flare Info Title
graphsTitle = uilabel(grid,'Text','Flare Info');
graphsTitle.HorizontalAlignment = 'center';
graphsTitle.FontSize = 22;
graphsTitle.FontWeight = 'bold';
graphsTitle.Layout.Row = 1;
graphsTitle.Layout.Column = [2 4];
% Slider Title
sliderTitle = uilabel(grid,'Text','Frame Number');
sliderTitle.FontSize = 22;
sliderTitle.FontWeight = 'bold';
sliderTitle.Layout.Row = 5;
sliderTitle.Layout.Column = [1 4];
sliderTitle.HorizontalAlignment = 'center';
% Slider Look
slider.Limits = [1 nFrames];
slider.MinorTicks = [];
slider.MajorTicks = [1:nFrames]; %1:bin.numberOfImages
%slider.Tooltip = 'Set Array 4 ToolTip';
slider.FontSize = 6;
slider.Layout.Row = 6;
slider.Layout.Column = [1, 4];
% SLIDER FUNCTION
changeslice_v2(slider, grid, nFrameApplOfStim, perfusionImgsVolume, flareBoundariesVolume, nFrames, flareMeanIntensities, flareAreas_mm);
The following is the slider function (changeslice_v2) I am calling from the main script. This is where I have been trying to implement cla. I only need to update the Perfusion Image with its respective flare contour and the markers for the area and intensity profiles.
% FUNCTION TO CHANGE SLICE NUMBER BASED ON SLIDER VALUE
function changeslice(slider, grid, nFrameApplOfStim, perfusionImgsVolume, flareBoundariesVolume, nFrames, flareMeanIntensities, flareAreas_mm)
% Change Frame With Slider
nslice = round(slider.Value);
perfusionImg = perfusionImgsVolume(:, :, nslice);
boundary = flareBoundariesVolume(:, nslice);
% Plot Perfusion Image to Overlay Flare Contour
ax2=uiaxes(grid);
ax2.Layout.Row = [2 4];
ax2.Layout.Column = 1;
imshow(perfusionImg,'Parent', ax2);
colormap(ax2, 'jet' );
xLabelInMM1 = xlabel(ax2, '|-------------------------- 45.29 mm --------------------------|', 'Fontsize', 16);
yLabelInMM1 = ylabel(ax2, '|---------------------------------------------------- 80.03 mm ----------------------------------------------------|', 'Fontsize', 16);
hold(ax2,'on')
colorbar(ax2, 'south', 'Color', 'red', 'FontWeight', 'bold', 'AxisLocation', 'in');
% Plot Flare Contour
if nslice ~= nFrameApplOfStim
if nslice ~= nFrameApplOfStim -1
if nslice >= nFrameApplOfStim
plot(ax2, boundary{1,1}(:,2), boundary{1,1}(:,1), 'red', 'LineWidth', 2.5);
else
plot(ax2, boundary{1,1}(:,2), boundary{1,1}(:,1), 'magenta', 'LineWidth', 2.5);
end
end
end
% STATISTICAL GRAPHS
% Flare Area Profile
ax3=uiaxes(grid);
ax3.Layout.Row = 2;
ax3.Layout.Column = [2 4];
xArea = 1:nFrames;
yArea = flareAreas_mm;
plot(xArea,yArea, 'Color', 'red','LineWidth', 4,'Parent', ax3);
ylim(ax3, [0,max(flareAreas_mm)]);
xlim(ax3, [0 nFrames]);
xticks(ax3, 0:5:nFrames);
% AreaUnder Curve
hold(ax3,'on')
arndrcrv=area(ax3, yArea);
arndrcrv.FaceColor= [0.99 0.88 0.88];
hold(ax3,'on')
% Line 4 Where Stim Was Applied
hold(ax3,'on')
nNaN = sum(isnan(flareMeanIntensities));
colorSTimFrames = [0.9 0.9 0.9];
rectangle(ax3, 'Position',[(nFrameApplOfStim-3) 0 (nNaN + 1) max(flareAreas_mm)], 'FaceColor', colorSTimFrames, 'EdgeColor', colorSTimFrames)
stimText = text(ax3, (nFrameApplOfStim-0.5), (max(flareAreas_mm*0.15)), 'LASER STIMULATION', 'FontSize', 14 ,'Rotation', 90);
% Plot Marker
marker4AreaGraph=plot(ax3, nslice, flareAreas_mm(nslice), 'o', 'Color', 'red', 'LineWidth', 3);
marker4AreaGraph.MarkerFaceColor = 'red';
marker4AreaGraph.MarkerSize = 15;
dt4AreaGraph = datatip(marker4AreaGraph, nslice, flareAreas_mm(nslice), 'Fontsize', 12);
marker4AreaGraph.DataTipTemplate.DataTipRows(1).Label = "Frame:";
marker4AreaGraph.DataTipTemplate.DataTipRows(2).Label = "Area:";
marker4AreaGraph.DataTipTemplate.DataTipRows(2).Format = '%.2f mm^{2}';
% Flare Intensity Profile Graph
ax5=uiaxes(grid);
ax5.Layout.Row = 3;
ax5.Layout.Column = [2 4];
xIntensity = 1:nFrames;
yIntensity = flareMeanIntensities;
plot(xIntensity, yIntensity, 'Color', 'green','LineWidth', 4,'Parent', ax5);
ylim(ax5, [0,1]);
xlim(ax5, [0,nFrames]);
xticks(ax5, 0:5:nFrames);
% AreaUnder Curve
hold(ax5,'on')
arndrcrv=area(ax5, yIntensity);
arndrcrv.FaceColor= [0.721568627450980 0.988235294117647 0.545098039215686];
% Mean Flare Intensifty
hold(ax5,'on')
% Line 4 Where Stim Was Applied
hold(ax5,'on')
rectangle(ax5, 'Position',[(nFrameApplOfStim-3) 0 (nNaN + 1) 1], 'FaceColor', colorSTimFrames, 'EdgeColor', colorSTimFrames)
stimText = text(ax5, (nFrameApplOfStim-0.5), 0.2, 'LASER STIMULATION', 'FontSize', 14 ,'Rotation', 90);
% Average Baseline
baselineMean = mean(flareMeanIntensities([1:nFrameApplOfStim]), "omitnan");
hold(ax5,'on')
line(ax5, [0 (nFrameApplOfStim - 3)], [baselineMean baselineMean], 'Color', 'blue','LineWidth', 1.5, 'LineStyle', '--');
% Average Intensity Perfusion
perfusionMean = mean(flareMeanIntensities([nFrameApplOfStim:end]), "omitnan");
hold(ax5,'on')
line(ax5, [(nFrameApplOfStim + 2) length(flareMeanIntensities)], [perfusionMean perfusionMean], 'Color', 'magenta','LineWidth', 1.5, 'LineStyle', '--');
% Plot Marker
hold(ax5,'on')
marker4intensityplot=plot(ax5, nslice, flareMeanIntensities(nslice), 'o', 'Color', 'green', 'LineWidth', 3);
marker4intensityplot.MarkerFaceColor = 'green';
marker4intensityplot.MarkerSize = 15;
dt4intensityplot = datatip(marker4intensityplot, nslice, flareMeanIntensities(nslice), 'Fontsize', 12);
marker4intensityplot.DataTipTemplate.DataTipRows(1).Label = "Frame:";
marker4intensityplot.DataTipTemplate.DataTipRows(2).Label = "FMI:";
marker4intensityplot.DataTipTemplate.DataTipRows(2).Format = '%.2f';
% SUMMARY - INFO PANEL
ax4=uipanel(grid, 'Title','Summary', 'TitlePosition', 'centertop', 'FontSize', 18, ...
'FontWeight','bold', 'BorderWidth', 2,'BackgroundColor','white');
ax4.Layout.Row = 4;
ax4.Layout.Column = [2, 4];
% Info 4 Display
% AREA
aveFlareArea_mm = mean(flareAreas_mm, 'all', "omitnan");
flareAreaSTD_mm = std(flareAreas_mm, "omitnan");
xArea(isnan(xArea)) = 0;
yArea(isnan(yArea)) = 0;
areaUnderAreaCurve = trapz(xArea, yArea); % Trapezoidal numerical integration
% FLARE INTENSITY PROFILE
aveFlareIntensity = mean(flareMeanIntensities([nFrameApplOfStim + 1:length(flareMeanIntensities)]),"omitnan");
flareIntensitySTD = std(flareMeanIntensities([nFrameApplOfStim + 1:length(flareMeanIntensities)]), "omitnan");
areaUnderIntensityCurve = trapz(xIntensity([nFrameApplOfStim + 1:end]), yIntensity([nFrameApplOfStim + 1:end]));
% BASELINE INTENSITY PROFILE
aveBaselineIntensity = mean(flareMeanIntensities([1: nFrameApplOfStim - 1]),"omitnan");
baselineIntensitySTD = std(flareMeanIntensities([1: nFrameApplOfStim - 1]), "omitnan");
totalFlareArea = uilabel(ax4);
totalFlareArea.Text = sprintf('Average Flare Area: %.3f mm%c', aveFlareArea_mm, [178]);
totalFlareArea.FontSize = 15;
totalFlareArea.Position= [10 120 330 180];
stdFlareArea = uilabel(ax4);
stdFlareArea.Text = sprintf('Flare Area STD: %c %.3f mm%c',[0177],flareAreaSTD_mm, [178]);
stdFlareArea.FontSize = 15;
stdFlareArea.Position= [10 90 330 180];
areaUnderCurv = uilabel(ax4);
areaUnderCurv.Text = sprintf('Area Under Area Curve: %.3f mm%c', areaUnderAreaCurve, [178]);
areaUnderCurv.FontSize = 15;
areaUnderCurv.Position= [10 55 370 190];
aveIntensity = uilabel(ax4);
aveIntensity.Text = sprintf('Average Flare Intensity: %.3f', aveFlareIntensity);
aveIntensity.FontSize = 15;
aveIntensity.Position= [10 25 330 190];
stdFlareIntensity = uilabel(ax4);
stdFlareIntensity.Text = sprintf('Flare Intensity STD: %c %.3f',[0177],flareIntensitySTD);
stdFlareIntensity.FontSize = 15;
stdFlareIntensity.Position= [10 0 330 180];
aveBaseIntensity = uilabel(ax4);
aveBaseIntensity.Text = sprintf('Average Base Intensity: %.3f', aveBaselineIntensity);
aveBaseIntensity.FontSize = 15;
aveBaseIntensity.Position= [10 -35 360 190];
stdBaseIntensity = uilabel(ax4);
stdBaseIntensity.Text = sprintf('Baseline Intensity STD: %c %.3f',[0177],baselineIntensitySTD);
stdBaseIntensity.FontSize = 15;
stdBaseIntensity.Position= [10 -60 360 180];
slider.Value = nslice;
end

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 17 Jun 2023
If you have performance issues, then you should be re-working your graphics a fair bit.
For performance, create your axes and titles and graphic objects once, and then as you go through the loop, update the graphics objects as needed. That might be something like
h = plot(nan,nan); %initialize
while true
stuff
set(h, 'XData', new_x_values, 'YData', new_y_values);
drawnow limitrate
end
or might involve using animatedline
Creating new graphics objects is a lot more expensive than updating the properties of existing graphics objects.
  3 Comments
Walter Roberson
Walter Roberson on 17 Jun 2023
The uiaxes, uipanel, various uilabel -- all of those can be created in advance, possibly set Visible off at the beginning. Then as you get new data, update only the properties needed
Miguel
Miguel on 23 Jun 2023
Walter, thank you so much for taking the time to answer to my question. It really helped me. My application is running super fast and smooth now.

Sign in to comment.

More Answers (0)

Categories

Find more on Specifying Target for Graphics Output in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!