close figure: return value
Show older comments
HI, i want to know when i figure is close
(here an example no sense)
clear all
f = figure;
for c=1:100
%%do something
c
end
if c
close(f);
end
if f is close
%do something
end
Answers (2)
Use isvalid
hF=figure;
isvalid(hF)
delete(hF)
isvalid(hF)
exist('hF','var')
clear hF
exist('hF','var')
Or, put the reference to the figure inside a try...catch...end structure.
1 Comment
vv=figure(); %%it's an example but i used countodown timer
What for? and without knowing what that was set for and what its callback is, nothing can say about what effect, if any it may be having.
But, timers are asynchronous as the reference article explains, the rest of the code goes on until the event is triggered.
I'd venture a guess the timer isn't needed here; what you're needing is simply a delay between the close function before the code proceeds to display the table...
function startupFcn(app, setting)
DURATION = 0.5; % DELAY (sec) before subsequent code executes
hF=figure();
% do whatever here w/ figure, data
ls=...; % fill the array
T = cell2table(ls);
close(hF);
START_TIME = tic(); % start delay
while toc(START_TIME)<DURATION, end % spin in place DURATION sec
app.UITable.Data=T; % and then display the table component
end
You'll have to empirically determine how long the delay needs be...to use a timer, the callback for it would have to be the line that displays the table
17 Comments
Sis isn't defined in above code and the above has nothing at all related to deleting a figure...you keep jumping all over the place.
Unless there were something far more time consuming is in the loop than what you've got; you're talking milliseconds unless length(Sis) is in the trillions. It looks here like you're trying to fabricate a uiprogressdlg, but it would need to be in the code at the point at which the actual operations that are consuming the time actually occur...and that isn't here at all as shown now; the only actual operations at all are nothing but gui stuf; nothing real is happening at all.
This conversation is far too disjointed to have much hope of progressing, sorry; need one consistent example that illustrates the whole problem and sticks onto the same issue.
So, where's the issue about closing a figure that began the whole thread? It's seemed to have disappeared entirely, and certainly using the progressdialog would simplify things from that end.
I'll make a couple comments on the above ---
1.
n=length(Sis);
length() is a VERY dangerous function; it's defined (for non-empty variables) as max(size(x)) and so can return either the number of rows OR the number of columns in an array, depending upon whether it is wider or longer. Use the specific dimension you need; as of R2020b, the height and width functions have been enhanced to work on arrays/matrices as well as just for tables; for new code I'd suggest using them.
Replace the above line with
nrows=height(Sis); % and then use nrows everywhere n was before.
2.
I'd strongly recommend rewriting the table-building code to first define the empty table and then to populate it. All of these variables can be set directly without any looping; that alone should cut your run time down noticeably rather than the dynamic reallocation you're doing; particularly if there are quite a number of rows in Sis.
Something like
[~,Sis]=CaricoSistemi2_Struct(Settings);
nrows=height(Sis);
VNAMES={'????'}; % where are the definitions of the variable names for the table???
VTYPES=[repmat({'double'},1,2),repmat({'string'},1,4),repmat({'double'},1,2)]; % make sure this is right
T=table('Size',[nrows,numel(VNAMES)],'VariableTypes',VTYPES,'VariableNames',VNAMES); % empty table to fill
% now populate the table from Sis data
T.Var1=[1:nrow].'; % <-- ls{i,1}=i;
T.Var2=[Sis.Sistema].'; % <-- ls{i,2}=Sis(i).Sistema;
data=cat(3,Sis.data); % presume is 2D array
T.Var3=string(squeeze(data(1,1,:))); % <-- ls{i,3}=string(Sis(i).data(1,1));
T.Var4=string(squeeze(data(end,1,:))); % <-- ls{i,4}=string(Sis(i).data(end,1));
...
where I've just used the default MATLAB table variable names in lieu of having a defined set.
Would need better description of what the content of the struct array Sis is to complete, but the basics are just translating across from one storage format to the table. Unfortunate that used arrays in the struct, otherwise could have just used struct2table directly. Might still could, actually, depending upon what the content really is.
Anyways, none of this still relates back to the original question about closing the figure before displaying the table, although working on cleaning up this part first is probably of a lot more value in spending some time and effort than is the graphics at this point. If you can create clean data, then displaying it will be much simpler to solve.
piero
on 23 Jun 2023
dpb
on 23 Jun 2023
>> nrows=width(Sis);
WRONG! rows should be HEIGHT(Sis), not WIDTH().
VTYPES={repmat({'double'},1,nrows),...
WRONG!
VTYPES can only add up to the total number of columns -- your table appeared to have only 9 variables so the total can't be more than that.
Also {repmat('{double'},1,2), ....} will create a cell array of cells, not a cell array; use [] around the outer constructor, not {}. I had a typo there, sorry...
Attach a copy of the Sis struct with the paperclip icon; use "save Sis" to create a .mat file and attach it.
dpb
on 23 Jun 2023
BTW, use the Code icon to format your code (the LH one in the CODE section) or select the code text and use Ctrl-E. I keep having to fix it... :(
VNAMES={'num','Strategy Name','First date','Last date','First trade','Last trade','Net Profit','Max DD','# trades'};
From those variable names it appears the data types should be
VTYPES=['double','categorical',repmat('datetime',1,4), repmat('double',1,3)];
instead. Confirm that and also adds up to 9 total.
I'd suggest creating shorter names and definitely get rid of the embedded blanks and special characters; those make for writing addressing expressions using them long and very cumbersome because all have to be quoted. "Brief but identifiable" is the mantra in creating variable names. I'd do something more like
VNAMES={'ID','Strategy','DateF','DateL','TradeF','TradeL','Profit','MaxDD','Trades'};
It's your call in the end and you may have better short names than those, but longer is NOT better here...
load matlab
nrows=width(Sis); % Sis is a row struct array, not column
VNAMES={'ID','Strategy','DateF','DateL','TradeF','TradeL','Profit','MaxDD','NTrades'};
VTYPES=[{'double'},{'string'},repmat({'datetime'},1,4),repmat({'double'},1,3)];
T=table('Size',[nrows,numel(VNAMES)],'VariableTypes',VTYPES,'VariableNames',VNAMES); % empty table to fill
% now populate the table from Sis data
T.ID=[1:nrows].';
T.Strategy=[Sis.Sistema].';
data=[Sis.data]; % N x size(Sis,2) array datetimes
T.DateF=data(1,:).'; % start date is first each
T.DateL=data(end,:).'; % last date is end each
try
[r1]=arrayfun(@(s)find(s.dailyprof,1),Sis);
[r2]=arrayfun(@(s)find(s.dailyprof,1,'last'),Sis);
T.TradeF=arrayfun(@(s,i)s.data(i),Sis,r1).';
T.TradeL=arrayfun(@(s,i)s.data(i),Sis,r2).';
catch
% at least one failed to match, will have to revert to direct loop processing
% doesn't happen in theis dataset, don't know if it's likely to be issue or not
end
Shows the beginnings; the thing with the lookup of first/last makes it more of a pain because there isn't a vectorized find built into MATLAB that will return the values by colum in an array; it only works globally. There's a mex submission on the FEX that does it by @Bruno Luong; but no way to use it here, but it'd be the ticket for final implementation.
We've got severe weather looking like is moving in; I gotta' go check on things...
Well, we got lucky last night, the cell w/ baseball+ hail and multiple tornados fell apart about 20 mi before it got to us...other than what hail damage there was, apparently all the tornados were in open country...
See if we can finish up the last few variables into the table...
E=cumsum([Sis.dailyprof]);
MDD=cummax(max(cummax(E,1),0)-E);
T.Profit=round(E(end,:)).';
T.MaxDD=round(MDD(end,:)).';
NTrades=[Sis.Ntradess];
T.NTrades=NTrades(end,:).';
head(T)
I compared those results to the values returned by your code for the first struct; I'm pretty sure they'll match for all.
See if that won't load the data more quickly; the only real issue is the one of the behavior of find in that it returns the empty result if the search isn't successful; that would be true if (and only if) there were no values that were ever nonzero in any data vector which doesn't seem as though that would be likely so I didn't do anything about it in the above code other than have the empty catch block; you'll just get no data for that set if it does occur.
I'd still recommend getting <Bruno's enhanced vectorized find function>(*) and using it instead of the arrayfun code above; it will be noticeably faster I'm sure and it has the feature that it also returns a uniform number of elements whether the search is successful or not so it won't crash on the case of no match; it returns a zero index for those columns that will have to test for,but it's easier to make that fixup than it is to deal with the different lengths.
(*) Download the files and put in a location on your MATLABPATH. I create and keep a special Utilities folder parallel to my default working folder and have it very early in the MATLABPATH for such things. The mex function has to be compiled; there's a supplied "findfirst_install" m-file that you run first that compils the supplied c-code; then use findfirst as any other MATLAB function, its syntax is very similar as to the builtin find function.
piero
on 24 Jun 2023
dpb
on 24 Jun 2023
dpb
on 25 Jun 2023
I'll be interested to know how much difference it makes in reading the data, time-wise.
piero
on 25 Jun 2023
dpb
on 25 Jun 2023
You can compare the time for this with your original code...
piero
on 25 Jun 2023
dpb
on 25 Jun 2023
I thought you said it was taking 10 sec or longer to read with your looping code; that's why you were in the morass of trying to add homegrown progress bars, having timing issues and graphics display problems????
I was/am recommending you should take the above code and put it into a callable function and replace the looping structure with it and see if that isn't fast enough you can get rid of all the rest and get on to the rest of the problem.
As another alternative on how to show the user something is happening, I have a couple apps that take a while that otherwise user can't tell anything is happening -- instead of a progress bar with an unknown time, I simply create a text box and every so often when a piece of code finishes and starts the next operation, it writes a "Processing This Part..." message...that updates every so often, just enough to let the user know that the code is alive and well...here you could put it in between each of the variables; but I'm guessing it's fast-enough now that it would just flicker on the screen.
Categories
Find more on Desktop in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!