I'd like to call the cftool from a function/script, do my fitting, store the variables to the workspace and then resume execution of my function. Naively, one could assume that assigning a handle to the GUI and then using waitfor(), like for a graphics object, would do the job, but that was a bit short-sighted.
Minimally this reads
h = cftool;
waitfor(h);
disp('happy fitting');
and of course does not work.
Cheers.
The cftool does not return a handle, so you need to search for it using findall:
cftool
f = findall(0,'Type','Figure');
waitfor(f(1))
disp('Happy fitting!')
If you have multiple figures f may have multiple values and it could cause some issues. So keep track of your figures and check which position has the gui handle, before you call waitfor.
Related
bayesopt draws figures like this:
How to access such figures in order to modify title or something? If I use gcf it is not guaranteed I get the correct figure because I could change focus to another figure window during execution.
Apparently bayesopt does not allow you to return a figure handle. So I suggest that on the line directly after your call to bayesopt you call h=gcf;, thus forcing your program to return the figure handle to h, which can then be modified at any desired time, even when moving to other figures.
results = bayesopt(fun,vars,Name,Value); % execute bayesian optimisation
h = gcf; % directly after optimisation grab a figure handle
Now you can modify properties in h, e.g. for the title you'd simply do
h.CurrentAxes.Title.String = 'Your plot title'
The reason this works is that MATLAB does not display figures until the full code has finished running. At least that's the case for my script, where I generate a figure, perform a few minutes of optimisation, then generate another figure. Both figures get displayed at the same time, i.e. when MATLAB has finished running the full program. There's thus no way you can click other figures when the code is running, since they are simply not there. If you happen to have older figures open (from other scripts), focus gets shifted to the latest created figure anyway, the moment it's created in the code (so not when it's displayed), thus you'd need to click a figure in the few milliseconds between the bayesopt call finished and the gcf call, which I'd say is so improbable that it's not worth considering, especially since it requires manual intervention.
As was pointed out in comments by Cris Luengo and Dev-iL, the figures are tagged and can thus be found using findobj:
h1 = findobj(0,'tag','bayesopt.MinObjective')
Each time I call the nlfilter function a progress bar window appears. How could I disable that window?. Is there an option like -q?
I'm processing an image by rows and applying a custom function, so the window generated when calling to the nlfilter function is bothering quite a lot and also decreasing the performance of my system.
Note that I'm only want disable the window momentarily.
The waitbar within MATLAB definitely reduces the performance of your code as well as gets really obnoxious when running long-running tasks on some operating systems as it can steal the focus of your keyboard/mouse randomly.
I personally create my own waitbar function and place it on the MATLAB path so that it is evaluated rather than the built-in.
I have a more complicated text-based progress bar, but the following function will simply print the messages to the command line. You could even remove the first block and have the contents simply be varargout = {[]}; and you will have no output.
function varargout = waitbar(varargin)
if nargin >= 2 && ischar(varargin{2})
disp(varargin{2})
elseif nargin >= 3 && ischar(varargin{3})
disp(varargin{3})
end
varargout = {[]};
end
Be sure to save this in waitbar.m somewhere high on your MATLAB path.
NOTE: This will silence all waitbars so if you want to restore the typical waitbar behavior, you will want to remove/rename this file.
In MATLAB is it be better (as far as optimization is concerned):
1)To have a function "foo" with a lot of inputs that come from the outputs from other functions
or
2)Save at the end of the functions the results to a results.mat file and load it in the "foo" function and minimize its inputs this way?
almost always: option 1.
As option 2 depends on file IO, and thus one write and one read to/from a hard disk, SSD or similar, it will likely lose out against keeping variables in RAM. Moreover, if you pass arguments to a function, and that function only reads them, no explicit copies of that variable are made. This is not true for the .mat file solution, as something that you already have in memory will be explicitly copied onto an extremely slow device (HDD, SSD), and then again read back into memory from the extremely slow device, just to save on a few input arguments.
So, unless you're working with big data sets and your variables give you out-of-memory errors, keep everything in RAM as much as possible.
You can minimize argument count by simply collecting data in a container data type. MATLAB has cell and struct for this purpose (or classdef, if you include value classes). You can transform this:
[outarg1, outarg2] = function(arg1, arg2, arg3,...)
into
[outarg1, outarg2] = function(S)
where
S = struct(...
'arg1', function1(X),...
'arg2', function2(X,Y,Z),...
'arg3', function3(X,Z),...
%// etc.
);
or
S = {
function1(X)
function2(X,Y,Z)
function3(X,Z)
%// etc.
}
or similar. Or you can make use of the special cell/functions called varargin/nargin and varargout/nargout:
varargout = function(varargin)
% rename input arguments
arg1 = varargin{1};
arg2 = varargin{2};
%// etc.
% assign all output arguments in one go
[varargout{1:nargout}] = deal(outargs{:}));
end % function
You can read more about all these things by typing help <thing> on the MATLAB command prompt. For example,
help cell
will give you a wealth of information on what a cell is and how to use it.
I think using global variables is a better way to optimize memory and processing requirements.
you can use keyword global.
I have created a MATLAB gui in order to run a certain simulation.
In this gui is one button to start the simulation. This button callback function will then excecute the calculations. This will off course result in a dataset with the results.
Furthermore in the interface is a plot area, and a selectbox to switch between different graphs, in order to show different aspects of the simulation results. Therefore the results must be available for other functions in the gui as well. This is a problem, since the callback function has no output
Two solutions I can think of are storing the dataset in a MAT-file, or using global variables. The first solution seems not really correct to me, and furthermore I learned that global variabeles must be avoided if possible. So what is the best solution here?
you could create a user defined class inheriting from the handle class that defines your callbacks, your callbacks then execute from "inside" the handle class instance
classdef mySimulation < handle
properties
hFigure
mySimResults
end
methods
function this = mySimulation(varargin)
hFigure = figure;
...
<build figure components>
...
end
function myButtonCallback(this, src, evnt)
this.mySimResults = runMySimulation;
...
<update plot etc>
end
function mySelectBoxCallback(this, src, evnt)
...
<update plots>
end
end
end
MATLAB offers certain functions for this. There is the function guidata, which can store one variable. This can for instance be used to pass around your gui handles. Furthermore there are the functions setappdata and getappdata. These functions are the way to transfer data between functions, and couple variables to a figure handle.
More information on the different methods can be read here.
This is supposed to be semantically more correct then using global variables. However, I am still curious why. Any comments?
I am tasked to design a GUI and I need to use variables and plots from a different mfile which I created earlier. I'm pretty confident about getting variables from the processing mfile but I'm not sure how to get the plots/figures.
So basically my question is whether I can get() a figure from my mfile and then set() an axes to that figure inside my GUI.
Note: The reason I am doing this is because I want to keep the processing of data separate from the GUI mfile. I could just dump all the processing in the callback of my process button but that's not good. I would also appreciate good coding practices for my case since I have never worked with GUI's before (only scripting with PHP and MATLAB)
Note2 (rundown of what has to be done): In the GUI we basically are supposed to load 2 files, we then press the "process" button and then 4 plots have to appear. All the processing code already exists in a previously written mfile (by me).
Thanks! :)
I figured it out myself! What I did was use gcf to get the current figure like so: output.worldmap = gcf I then passed the object back like so: setappdata(0,'output',output) and grabbed it again inside my callback function like so: getappdata(0,'output') and used the following function to set the axes set(output.worldmap,'CurrentAxes',handles.axes_worldmap) I also made sure that the correct axis was set before I actually ran my mfile which does the processing with axes(handles.worldmap)