Plot command converting waitbar to figure

5 Ansichten (letzte 30 Tage)
Jessica Hiscocks
Jessica Hiscocks am 23 Mai 2020
Kommentiert: Walter Roberson am 20 Dez. 2020
I decided to add a waitbar to a function called by my app. This function takes in several user parameters, and overlays a plot on a pre-existing figure. Adding a waitbar to other similar functions (those drawing with the patch command) was no problem, but in this one drawing with the plot command, it actually draws the figure inside the text of the waitbar, and then causes a crash when it tries to update the waitbar. The waitbar is converted into a figure. How do I stop the plot command targeting the waitbar?
Thank you
function [ScriptReturned]=appT3annotateUnitShape(X,Y,grainIds,ScaleFactor,GSscale,LineWdth,LineColour,FillFace,FillColour,grains,GrainsVarName)
%ANNOTATEUNITSHAPE draws a unit cell over the active ebsd or grain map. Possible unit cells are HCP or cubic.
%note that this differs from annotateUnitCell because this function
%uses the crystalShape function while that one manually draws the unit cell.
%X and Y are the coordinates on the map to be used, grainIds lists the grains for which unit cells will be drawn.
% ScaleFactor >1 increases the size of the unit cell, while
%values <1 decrease it and GSscale=1 causes scaling with grain area.
%LineWdth,LineColour control the outline of the
%unit cell. FillFace,FillColour control the filling of the faces of the
%unit cell (FillFace=1 is fill faces), and the colour of fill.
%Grains passes the grains variable. The name is passed as a string for scripting purposes.
%the returned cell array is the script data
%version 2: reduce scale by factor of 12 to match crystalShape output. Now
%using grainIds instead of crystal ori, because this gives grain size AND
%orientation info. Orthogonal option removed, now separate in
%App designer function, part of Annotate tab T3
h = waitbar(0,'1','Name','Annotating...','CreateCancelBtn','setappdata(gcbf,''canceling'',1)');%draw a progress bar
setappdata(h,'canceling',0);
legend off
hold on
for i=1:size(grainIds,1)
% Check for clicked Cancel button
if getappdata(h,'canceling')
delete(h)%close waitbar
break
end
if mod(i,10)==1 %every 10 loops update waitbar
perc = round(100*i/size(grainIds,1),0);
waitbar(perc/100,h,sprintf('%d%% along...',perc))
end
%allow for points without indexed data that somehow slip through
try
crystalOri=grains(grainIds(i)).meanOrientation;
cs=grains(grainIds(i)).CS;
catch
continue
end
%check for flag to enable grain size scaling.
if GSscale==1
%scale by ScaleFactor and grain area
gs=sqrt(grains(grainIds(i)).area)*ScaleFactor;
else %scale by ScaleFactor
gs=ScaleFactor;
end
%check which shape to plot
if ismember(cs.lattice, {'cubic', 'orthorhombic', 'triclinic', 'monoclinic', 'tetragonal'})
cS = crystalShape(Miller({1,0,0},{0,1,0},{0,0,1},cs));
elseif ismember(cs.lattice, {'hexagonal', 'trigonal', 'rhombohedral'})
cS = crystalShape.hex(cs);
else %use this option to flag errors
disp('unit cell type not found. Skipping this point');
continue %skips plot command and goes to next loop
end
%must plot high enough above plane. so cell doesn't 'punch through' map
%crystalShape unit cell is one unit, times scale factor (which may be scaled by the grain size above). Threfore, set
%z=scale factor
%Add 'padding factor' to allow for rotated corners
if strcmpi(getMTEXpref('zAxisDirection'),'intoPlane')
Z=-gs*1.4;
else %if z out of plane Ensure v_T(z) is all >0 to ensure all lines above
%ebsd map surface and visible
Z=gs*1.4;
end
%plot as lines or filled depending on fillface setting
if FillFace==0
plot(X(i),Y(i),Z,crystalOri*cS*gs,'FaceAlpha',0,'LineWidth',LineWdth,'Edgecolor',LineColour,'Tag','Annotate');
elseif FillFace==1
plot(X(i),Y(i),Z,crystalOri*cS*gs,'FaceColor',FillColour,'LineWidth',LineWdth,'Edgecolor',LineColour,'Tag','Annotate');
end
end
hold off
delete(h)%close waitbar
ScriptReturned{1}='%ANNOTATEUNITSHAPE draws an automatically selected unit cell shape (either HCP or cubic) over an ebsd or grain map previously drawn.';
ScriptReturned{2,1}='%X and Y are the coordinates on the map to be used, orientations are from the grain data via grainIds ';
ScriptReturned{end+1}='legend off;hold on;';
ScriptReturned{end+1}='%use length of X coordinate to get loop iterations';
ScriptReturned{end+1}='for i=1:length(grainIds)';
ScriptReturned{end+1}='%filter out points without indexed data that somehow slip through';
ScriptReturned{end+1}='try';
ScriptReturned{end+1}=['crystalOri=',GrainsVarName,'(grainIds(i)).meanOrientation;'];
ScriptReturned{end+1}=['cs=',GrainsVarName,'(grainIds(i)).CS;'];
ScriptReturned{end+1}='catch';
ScriptReturned{end+1}='continue';
ScriptReturned{end+1}='end';
ScriptReturned{end+1}='%check for flag to enable grain size scaling';
ScriptReturned{end+1}='if GSscale==1';
ScriptReturned{end+1}=['gs=sqrt(',GrainsVarName,'(grainIds(i)).area)*ScaleFactor;'];
ScriptReturned{end+1}='else %use unit value and scale factor only';
ScriptReturned{end+1}='gs=ScaleFactor;';
ScriptReturned{end+1}='end';
ScriptReturned{end+1}='%check which shape to plot';
ScriptReturned{end+1}='if ismember(cs.lattice, {''cubic'', ''orthorhombic'', ''triclinic'', ''monoclinic'', ''tetragonal''})';
ScriptReturned{end+1}='cS = crystalShape(Miller({1,0,0},{0,1,0},{0,0,1},cs));';
ScriptReturned{end+1}='elseif ismember(cs.lattice, {''hexagonal'', ''trigonal'', ''rhombohedral''})';
ScriptReturned{end+1}='cS = crystalShape.hex(cs);';
ScriptReturned{end+1}='else %use this option to flag errors';
ScriptReturned{end+1}='disp(''unit cell type not found. Skipping this point'');';
ScriptReturned{end+1}='continue %skips plot command and goes to next loop';
ScriptReturned{end+1}='end';
ScriptReturned{end+1}='%must plot high enough above plane. so cell doesn''t ''punch through'' map';
ScriptReturned{end+1}='%crystalShape unit cell is one unit, times scale factor (which may be scaled by the grain size above). Threfore, set z=scale factor and Add ''padding factor'' to allow for rotated corners';
ScriptReturned{end+1}='if strcmpi(getMTEXpref(''zAxisDirection''),''intoPlane'')';
ScriptReturned{end+1}='Z=-gs*1.4;';
ScriptReturned{end+1}='else %if z out of plane Ensure v_T(z) is all >0 to ensure all lines above ebsd map surface and visible';
ScriptReturned{end+1}='Z=gs*1.4;';
ScriptReturned{end+1}='end';
ScriptReturned{end+1}='%plot as lines or filled depending on fillface setting';
ScriptReturned{end+1}='if FillFace==0';
ScriptReturned{end+1}='plot(X(i),Y(i),Z,crystalOri*cS*gs,''FaceAlpha'',0,''LineWidth'',LineWdth,''Edgecolor'',LineColour);';
ScriptReturned{end+1}='elseif FillFace==1';
ScriptReturned{end+1}='plot(X(i),Y(i),Z,crystalOri*cS*gs,''FaceColor'',FillColour,''LineWidth'',LineWdth,''Edgecolor'',LineColour);';
ScriptReturned{end+1}='end';
ScriptReturned{end+1}='end';
ScriptReturned{end+1}='hold off';
end

Akzeptierte Antwort

Cris LaPierre
Cris LaPierre am 20 Dez. 2020
When you plot in an app. you should specify which axes to plot into using the following syntax: plot(ax,___)
For a GUIDE app, it would be something like this
plot(handles.axes1,x,y)
In app designer, it would be similiar to
plot(app.UIAxes,x,y)
  1 Kommentar
Walter Roberson
Walter Roberson am 20 Dez. 2020
When you use legend off or any of the other plotting commands including plot(), and you do not specify which container object to apply the command to, then the graphic command will go looking for the appropriate container object. However, the search that is done does not look for uifigure or their children. A command such as legend off would not know that it is to apply the command to some uiaxes . There is effectively no "current" uiaxes. So legend would hunt around, and will create a complete figure and axes if necessary. But if your most recent command was waitbar() then because waitbar() happens to create a traditional figure, the figure created by waitbar() might be the "current" figure for the purposes of the search done by legend and similar commands, so legend and plot would happily draw inside the figure created for waitbar().
The waitbar() is not being converted into a figure: waitbar() is already a figure... possibly the only traditional figure you have.
When you are using App Designer, instead of using waitbar() you would be better using https://www.mathworks.com/help/matlab/ref/uiprogressdlg.html . Which does not in itself solve the problem that you are asking to plot() and legend() without specifying the container to apply against, but at least would have saved you from having the symptoms turn out like this.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Dialog Boxes finden Sie in Help Center und File Exchange

Produkte


Version

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by