How to clear the last line in the command window - matlab

I'm curious about the progress of the running program and I print some information about the current iteration such as:
for i = 1:N
...
...
msg = sprintf('Processed %d/%d', i, N);
display(msg)
end
I don't want to print the progress on separate lines, instead, I want the last line to replace the previous one. I don't want to use clc which clears all the content.
I know that '\b' can clear the last character (like backspace) and I can create a function with a for loop which clears the items till the previous new line before the last. But is there a better way to do that? If not, how can I check whether the last character on the command line is a new line or not?

I've looked at the problem, a while ago. And I've noticed that the character \r (used to erase the last line) works with matlab in command-line (-nodesktop) but not with the graphic mode...
The best solution I found is to do something like that:
n=0;
for ...
...
fprintf(repmat('\b',1,n));
fprintf(msg);
n=numel(msg);
end

Yair Altman has a very nice example on his blog of how you can use the backspace control-character (\b) to do what you want but in an easier way than you were considering. Modifying your code to resemble his example, you could do something like this:
reverseStr = '';
for i = 1:N
...
...
msg = sprintf('Processed %d/%d', i, N);
fprintf([reverseStr, msg]);
reverseStr = repmat(sprintf('\b'), 1, length(msg));
end

I use 'dispstat' function just for this purpose. It can update the previous output which is a missing function of default 'disp'. Very simple to use. It can be downloaded from here: http://www.mathworks.com/matlabcentral/fileexchange/44673-overwritable-message-outputs-to-commandline-window
***Sample usage:
dispstat('','init'); % One time only initialization
dispstat(sprintf('Begining the process...'),'keepthis','timestamp');
for i = 97:100
dispstat(sprintf('Progress %d%%',i),'timestamp');
%doing some heavy stuff here
end
dispstat('Finished.','keepprev');
***Output:
11:25:37 Begining the process...
11:25:37 Progress 100%
Finished.
All the best

Is this about what you are looking for
%# create title
fprintf('processed: %03d',0)
for i=1:10
%# delete last three digit number and replace with new
%# loop index
fprintf('\b\b\b\b %03d',i);
%# process here
pause(.5)
end
%# clear line
fprintf('\n');
But if your code displays other results this won't work. and you might want to consider using a message box to update progress.

Another solution that overwrites the entire previous line relies on the \r formatting character,
ctrl=0;
while ctrl<5
fprintf('\rctrl: %i',ctrl);
ctrl=ctrl+1;
pause(2); % To highlight overwrite
end
fprintf('\n'); % Don't forget the newline

Related

Stop/pause MatLab execution for any underflow and overflow [duplicate]

Is it possible to add a customized dbstop condition to Matlab?
Recently I found myself with out of bounds values in multiple variables, one way to track down the first occurance of this would be to set a conditional breakpoint on each line where these values are updated. However, I hope there is an easier way to do this.
I have recently had to track down a NaN which was fairly trivial due to:
dbstop if naninf
Hence I hope that it is possible to get something like:
dbstop if anything outside myBound
or
dbstop if myVariable outside myBound
I would of course be willing to take the performance hit that one may expect.
If you use the editor, you can set a stop as normal, right-click on it, select "set/modify condition" and enter the condition (the stop will turn from red to yellow).
From command line, you can use
dbstop in file if expression
dbstop in file at location if expression
e.g.
dbstop in myFile at 200 if (~isempty(var) && var > 3)
as mentioned by #LuisMendo.
The second option may be more useful, since the first one seems to be only evaluated at the start of the file. In other words, it doesn't seem to be possible to have a similarly generic expression as dbstop if naninf that checks for certain values across an entire file.
The problem with using the form "DBSTOP in FILESPEC if EXPRESSION" of dbstop is that it sets a breakpoint only at the first line of the file. A solution is to use the form "DBSTOP in FILESPEC at LINENO if EXPRESSION" to set a breakpoint at each line.
Consider the following example script, saved on a file called testfile.m.
clear all
for m = 1:10;
k = 2*m
end
Say we want to stop if variable k exceeds the value 6. We first automatically set the breakpoints in all lines of this file:
file = 'testfile.m';
varname = 'k';
expression = 'k>6'; %// it should be 'exist(''k'')&&k>6', but that's added later
%// Determine number of lines of file:
fid = fopen('testfile.m');
cont = 1;
nlines = 0;
while cont
readline = fgetl(fid);
cont = ~isequal(readline,-1);
nlines = nlines + cont;
end
fclose(fid);
%// Set breakpoint at each line. We need eval for this
for n = 1:nlines
eval(['dbstop in ' file ' at ' num2str(n) ' if ( exist(''' varname...
''') && ( ' expression ' ) )'])
end
Now, after running the above (check that every line of testfile.m has a yellow breakpoint), run testfile and check values when it stops:
This is admittedly a little cumbersome if you have several variables or files. Also, I'm not sure how many simultaneous breakpoints Matlab supports (we are using one for each program line).
Thinking outside the box - you could write a class to hold your variable. There you could have a customized setter that will raise a warning if you violate boundaries. dbstop if warning should then be enough.

MATLAB: Permanently set "Text Update Function" for Data Cursor in figures

Problem: I use MATLAB for science, and I often need more than 4 significant digits. Every time I use Data Cursor in a figure's GUI, I need to manually right-click on the point, Select Text Update Function... or Edit Text Update Function..., and navigate to the folder where I saved the function whose callback prints more than 4 (e.g. 8) significant figures. This is annoying and there should be a way to automatically change this.
Ideal answer: I want this done permanently for all figures, e.g. in a function that changes default settings in my startup.m file.
Good enough answer: I want a wrapped function to which I give the figure handle and it fixes this for me.
I humbly await SO's infinite wisdom.
The permanent solution
would be, to edit the default_getDatatipText.m function.
You can find it in:
C:\...\MATLAB\R20xxx\toolbox\matlab\graphics\#graphics\#datacursor
There you will find the line:
DEFAULT_DIGITS = 4; % Display 4 digits of x,y position
Edit it as desired, you can't do much harm, but make a backup before if you want.
Alternative solution:
There is also the possibility of custom data tips: Tutorial at Matlab Central
It could finally look like this:
(additional text outside data-tips was post-processed)
And as you're talking about precision. The data-tip always snaps to the closest data-point. It doesn't show interpolated data at the clicked position.
The permanent answer given by thewaywewalk doesn't work anymore in R2015a, and probably later ones. So here I share my solution for both the temporary and permanent solution
Temporary solution (for a single figure):
The following function contains the update function as a nested function. Call datacursorextra to apply it to the current figure, or datacursorextra(fig) to apply it to some figure fig.
function datacursorextra(fig)
% Use current figure as default
if nargin<1
fig = gcf;
end
% Get the figure's datacursormode, and set the update function
h = datacursormode(fig);
set(h,'UpdateFcn',#myupdatefcn)
% The actual update function
function txt = myupdatefcn(~,event)
% Short-hand to write X, Y and if available Z, with 10 digit precision:
lbl = 'XYZ';
txt = arrayfun(#(s,g)sprintf('%s: %.10g',s,g), lbl(1:length(event.Position)), event.Position,'uniformoutput',false);
% If a DataIndex is available, show that also:
info = getCursorInfo(h);
if isfield(info,'DataIndex')
txt{end+1} = sprintf('Index: %d', info.DataIndex);
end
end
end
Permanent solution (apply to all figures by default):
I have not found a way to set a default UpdateFcn for the data cursor, but it is possible to add some code which will be called every time a new figure is created. Add the following line to your startup.m:
set(0,'defaultFigureCreateFcn',#(s,e)datacursorextra(s))
and make sure the datacursorextra function given above is available in your Matlab path.
#caspar's solution works very well.
You can also update the txt{} part of the solution with
if isfield(info,'DataIndex')
DataIndex = [info.DataIndex];
txt{end+1} = sprintf('Index: %d\n', DataIndex(1));
end
This will enable you to update the Index field when you have multiple pointers in the same figure.

Interpret the matlab code

I'm a Java programmer and have no background of matlab hence I'm really clueless with these lines of code from MATLAB. When I run the code I got an error :
??? Undefined function or variable 'nfile'.
Error in ==> texture_id at 29
fprintf(' \nneural network processing \n',nfile);
I understand that 'path' is a variable that stores string, 'demo' is boolean, but for the other lines, I don't want to assume what it does...Can you please help me and explain each lines?
Here's the code:
path = 'C:\Users\Dais\Documents\MATLAB\Data Sets\';
demo = true;
elfile = dir('*.jpg');
[lu ri] = size(elfile); feat=zeros(lu,29); nomf=cell(lu,1);
for nfi = 1:lu
nfile = elfile(nfi).name;
fprintf(' feature extraction file: %s \n',nfile);
nomf{nfi} = upper(nfile);
feat(nfi,:) = feature_ex([path nfile],demo);
end
fprintf(' \nneural network processing \n',nfile);
I would guess that whats happening here is that elfile = dir('*.jpg'); does not find any jpegs in the local directory and hence lu is empty and nfile is never populated. Place a breakpoint there in the code and check this. The way I would set up the loop would be something like this:
for nfi=1:numel(elfile)
As #Rody Oldenhuis said, use doc and help to elarn more about each function (or press F1 when the cursor is in the function name) but this should get you started..
%Looks for all files with extention .jpg in current directory
elfile = dir('*.jpg');
%lu and ri hold the rows, column lengths of elfile respectively
[lu ri] = size(elfile);
%creates an array of zeros of dimensions lu rows by 29 columns
feat=zeros(lu,29);
%creates an empty cell array (doc cell) dimensions lu rows by 1
nomf=cell(lu,1); columns
for nfi = 1:lu %look through all files
nfile = elfile(nfi).name; %get index nfi file
fprintf(' feature extraction file: %s \n',nfile); %print string
nomf{nfi} = upper(nfile); %upper case
feat(nfi,:) = feature_ex([path nfile],demo); %some external function
end
fprintf(' \nneural network processing \n',nfile); %print string
Rather than explain all and everything about MATLAB, I'll say this: MATLAB is interactive! And, one of the things why you pay good money for MATLAB, is that the documentation is awesome, and getting help is super easy.
For instance, you can type help <command> on the MATLAB command line, and get a short help on that command, or doc <command> to get the complete documentation, often with examples and demonstrations. The whole documentation is also online, should you prefer Google and being in a browser.
Should you have a script or function or class that has problems, you can issue dbstop if error, so that you drop into the debugger when an error occurs, and then you can view the contents of all variables just prior to the error, type new commands to investigate the error, etc. You can set breakpoints by clicking on the line number next to where you want to break, dbstep then makes a single step, dbup moves you up a level, etc. Have a look at doc dbstop.
You can select portions of code and press F9, which will execute those lines of code. Note that that is equivalent to copy-pasting the code to the command window and running it, so you will often have problems with undefined variables (and similar problems) that way (this or something similar is what I suspect happened in your particular case, as the code you posted should not give that error).

Customize dbstop in MATLAB

Is it possible to add a customized dbstop condition to Matlab?
Recently I found myself with out of bounds values in multiple variables, one way to track down the first occurance of this would be to set a conditional breakpoint on each line where these values are updated. However, I hope there is an easier way to do this.
I have recently had to track down a NaN which was fairly trivial due to:
dbstop if naninf
Hence I hope that it is possible to get something like:
dbstop if anything outside myBound
or
dbstop if myVariable outside myBound
I would of course be willing to take the performance hit that one may expect.
If you use the editor, you can set a stop as normal, right-click on it, select "set/modify condition" and enter the condition (the stop will turn from red to yellow).
From command line, you can use
dbstop in file if expression
dbstop in file at location if expression
e.g.
dbstop in myFile at 200 if (~isempty(var) && var > 3)
as mentioned by #LuisMendo.
The second option may be more useful, since the first one seems to be only evaluated at the start of the file. In other words, it doesn't seem to be possible to have a similarly generic expression as dbstop if naninf that checks for certain values across an entire file.
The problem with using the form "DBSTOP in FILESPEC if EXPRESSION" of dbstop is that it sets a breakpoint only at the first line of the file. A solution is to use the form "DBSTOP in FILESPEC at LINENO if EXPRESSION" to set a breakpoint at each line.
Consider the following example script, saved on a file called testfile.m.
clear all
for m = 1:10;
k = 2*m
end
Say we want to stop if variable k exceeds the value 6. We first automatically set the breakpoints in all lines of this file:
file = 'testfile.m';
varname = 'k';
expression = 'k>6'; %// it should be 'exist(''k'')&&k>6', but that's added later
%// Determine number of lines of file:
fid = fopen('testfile.m');
cont = 1;
nlines = 0;
while cont
readline = fgetl(fid);
cont = ~isequal(readline,-1);
nlines = nlines + cont;
end
fclose(fid);
%// Set breakpoint at each line. We need eval for this
for n = 1:nlines
eval(['dbstop in ' file ' at ' num2str(n) ' if ( exist(''' varname...
''') && ( ' expression ' ) )'])
end
Now, after running the above (check that every line of testfile.m has a yellow breakpoint), run testfile and check values when it stops:
This is admittedly a little cumbersome if you have several variables or files. Also, I'm not sure how many simultaneous breakpoints Matlab supports (we are using one for each program line).
Thinking outside the box - you could write a class to hold your variable. There you could have a customized setter that will raise a warning if you violate boundaries. dbstop if warning should then be enough.

Displaying information from MATLAB without a line feed

Is there any way to output/display information from a MATLAB program without an ending line feed?
My MATLAB program outputs a number a bit now and then. Between outputting the number the program does a lot of other stuff. This is a construct mainly to indicate some kind of progress and it would be nice not to have a line feed each time, just to make it more readable for the user. This is approximately what I'm looking for:
Current random seed:
4 7 1 1
The next output from the program would be on the same row if it is still doing the same thing as before.
I've read the doc on disp, sprintf, and format but haven't found what I'm looking for. This doesn't mean it isn't there. ;)
The fprintf function does not add a line feed unless you explicitly tell it to. Omit the fid argument to have it print to the Command Window.
fprintf('Doing stuff... ');
for i = 1:5
fprintf('%d ', i);
% do some work on that pass...
end
fprintf(' done.\n'); % That \n explicitly adds the linefeed
Using sprintf won't quite work: it creates a string without a line feed, but then if you use disp() or omit the semicolon, disp's own display logic will add a line feed.