You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
close figure: return value
5 views (last 30 days)
Show older comments
Answers (2)
dpb
on 22 Jun 2023
Edited: dpb
on 23 Jun 2023
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
piero
on 23 Jun 2023
Edited: piero
on 23 Jun 2023
txk but i don't resolve my problem...
i write a piece of code:
function T=CaricaListaStrategie_Struct2(Sis)
for i=1:length(Sis)
if i==1
vv=figure(); %%it's an example but i used countodown timer
end
%% filled the array
end
close(vv);
T = cell2table(ls );
end
end
function startupFcn(app, setting)
T=CaricaListaStrategie_Struct2(setting);
app.UITable.Data=T;
end;
I want to draw the figure 'vv' but when I close it I want it to create table T (app.UITable.Data=T) Instead I see that while figure "F" is closing, it creates the table for me (not after but during)
i read this post:
but i don't know how can apply it in app designer
dpb
on 23 Jun 2023
Edited: dpb
on 23 Jun 2023
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
piero
on 23 Jun 2023
Edited: dpb
on 23 Jun 2023
ok i post complete function code
function T=CaricaListaStrategie_Struct2(Settings)
fh=figure('Position',[410 210 450 100],'toolbar','none','menu','none','numbertitle', 'off');
ax = axes(fh,'Position',[.1 .4 .8 .05],'box','on','xtick',[],'ytick',[],...
'color',[0.9375 0.9375 0.9375],'xlim',[0,1],'ylim',[0,1]); %gray94
title(ax,'Checking strategy ')
ph = patch(ax,[0 0 0 0],[0 0 1 1],[0.67578 1 0.18359]); %greenyellow
th = text(ax,1,1,'0%','VerticalAlignment','bottom','HorizontalAlignment','right');
for i=1:length(Sis)
%%LOAD T DATA!
ph.XData = [0 i/n i/n 0];
th.String = sprintf('%d/%d',i,n);
drawnow %update graphics
end
end
i give wait count==length(Sis) to close figure and return main
dpb
on 23 Jun 2023
Edited: dpb
on 23 Jun 2023
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.
piero
on 23 Jun 2023
Edited: dpb
on 23 Jun 2023
I can't post the code where in the for loop it downloads the .txt file (save in Sis) data because you would have in fact an incomplete code..I think I'll do you a favor by simplifying the code..(because it's a long code and they often tell me to simplify it before posting it).. Anyway, the cycle also lasts10 seconds .. so I need a counter of the n. of files I'm reading.. now I try uiprogressdlg thanks anyway.. But I'll post it in full so you see the chaos
code function complete
function T=CaricaListaStrategie_Struct2(Settings)
%%***************** AGGIUNTO PER GENERARE LA BARRA DI PROGRESSIONE*****
% Set up the progress bar axis
%https://it.mathworks.com/matlabcentral/answers/500824-how-to-add-a-waitbar-into-an-app-created-in-app-designer-not-in-a-separate-figure
% fh = clf();
% fh = uifigure('Position',[410 210 450 100]);
fh=figure('Position',[410 210 450 100],'toolbar','none','menu','none','numbertitle', 'off');
ax = axes(fh,'Position',[.1 .4 .8 .05],'box','on','xtick',[],'ytick',[],...
'color',[0.9375 0.9375 0.9375],'xlim',[0,1],'ylim',[0,1]); %gray94
title(ax,'Checking strategy ')
% Create empty patch that will be updated
ph = patch(ax,[0 0 0 0],[0 0 1 1],[0.67578 1 0.18359]); %greenyellow
% Create the percent-complete text that will be updated
th = text(ax,1,1,'0%','VerticalAlignment','bottom','HorizontalAlignment','right');
%%*****************
[~,Sis]=CaricoSistemi2_Struct(Settings);
ls=[];
n=length(Sis);
for i=1:length(Sis)
ls{i,1}=i;
ls{i,2}=Sis(i).Sistema;
ls{i,3}=string(Sis(i).data(1,1));
ls{i,4}=string(Sis(i).data(end,1));
d=find(Sis(i).dailyprof~=0);
if ~isempty(d)
ls{i,5}=string(Sis(i).data(d(1),1));
ls{i,6}=string(Sis(i).data(d(end),1));
end
%%*******************
D=Sis(i).dailyprof;
E=cumsum(D,1);
CmaxDaily=cummax(E,1);
CmaxDaily(1,:)=max(CmaxDaily(1,:),0); %nella prima riga quelli inferiori di 0 li metto = 0 (per evitare che calcola il maxdd sbagliato nella prima riga qualora ci fosse una equity negativa
DD=CmaxDaily-E;
MDD=cummax(DD);
%%********************
ls{i,7}=round(E(end));
ls{i,8}=round(MDD(end));
ls{i,9}=Sis(i).Ntradess(end);
%%*****contatore barra progressione*****
ph.XData = [0 i/n i/n 0];
%th.String = sprintf('%.0f%%',round(i/n*100));
th.String = sprintf('%d/%d',i,n);
drawnow %update graphics
end
T = cell2table(ls );
end
dpb
on 23 Jun 2023
Edited: dpb
on 23 Jun 2023
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
>> nrows=width(Sis);
VNAMES={'num','Strategy Name','First date','Last date','First trade','Last trade','Net Profit','Max DD','# trades'};
VTYPES={repmat({'double'},1,nrows),repmat({'string'},1,nrows),repmat({'string'},1,nrows),repmat({'string'},1,nrows),repmat({'string'},1,nrows),repmat({'string'},1,nrows),repmat({'double'},1,nrows),repmat({'double'},1,nrows),repmat({'double'},1,nrows)};
T=table('Size',[nrows,numel(VNAMES)],'VariableTypes',VTYPES,'VariableNames',VNAMES);
Error using table
Specify variable types as a string array or a cell array of character vectors, such as ["string", "datetime", "double"].
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...
dpb
on 24 Jun 2023
Edited: dpb
on 24 Jun 2023
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)
ID Strategy DateF DateL TradeF TradeL Profit MaxDD NTrades
__ _______________________________________________________________________ ___________ ___________ ___________ ___________ __________ _____ _______
1 "BP_T-Live 2023 Bp Rev Bool 30 min Over" 01-Jan-2008 22-Jul-2023 08-Jan-2008 16-Jun-2023 1.5873e+05 12965 1172
2 "BP_T-Live 2023 Bp Tf 60 min Bias Over" 01-Jan-2008 22-Jul-2023 29-Jan-2010 16-Jun-2023 71999 6026 478
3 "CL_T-Live 2022 Crude Oil Tf 30 min D0 Short Over - ALTRI" 01-Jan-2008 22-Jul-2023 18-Jun-2008 22-May-2023 50030 7910 282
4 "CL_T-Live 2022 Crude Oil 5 min TF ORB Intra" 01-Jan-2008 22-Jul-2023 19-Jan-2010 15-Jun-2023 85080 11630 904
5 "CL_T-Live 2022 Crude Oil 5 min TF ORB Over" 01-Jan-2008 22-Jul-2023 19-Jan-2010 16-Jun-2023 1.9893e+05 20460 681
6 "CL_T-Live 2022 Crude Oil Tf 5 min D0 D1 Intra" 01-Jan-2008 22-Jul-2023 13-Jan-2010 16-Jun-2023 87150 16590 1313
7 "CL_T-Live 2022 Crude Oil Tf 5 min D0 D1 Intra solo ptn Weekly" 01-Jan-2008 22-Jul-2023 16-Feb-2010 16-Jun-2023 87590 15050 1307
8 "CL_T-Live 2022 Crude Oil Tf 5 min D0 D1 Intra solo ptn Weekly - SHORT" 01-Jan-2008 22-Jul-2023 13-Feb-2008 08-Jun-2023 74460 14830 708
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 25 Jun 2023
...
T.ID=[1:nrows]';
T.Strategy=[Sis.Sistema]';
data=[Sis.data];
T.DateF=data(1,:)';
T.DateL=data(end,:)';
...
Elapsed time is 0.020781 seconds.
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,:).';
Elapsed time is 0.020048 seconds.
but I have seen that the weather varies all the time
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.
piero
on 25 Jun 2023
Edited: piero
on 25 Jun 2023
the code where I actually asked for help (I did it some time ago and I didn't remember that what takes time is reading the .txt file)(%[~,Sis]=CaricoSistemi2_Struct(Settings);) I put the counter inside this and fix it. The counter is used in the record reading phase, not in processing which is fast.
I apologize for the confusion I made
Anyway, now the problem is solved thanks
See Also
Categories
Find more on Characters and Strings 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!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)