How to Loop Subplots with Updated Outputs in Matlab? - matlab

I want to create a frontend where the user can browse pictures forward by pressing Enter.
Pseudo-Code
hFig=figure
nFrames=5;
k=1;
while k < nFrames
u=signal(1*k,100*k,'data.wav'); % 100 length
subplot(2,2,1);
plot(u);
subplot(2,2,2);
plot(sin(u));
subplot(2,2,3);
plot(cos(u));
subplot(2,2,4);
plot(tan(u));
% not necessary but for heading of overal figure
fprintf('Press Enter for next slice\n');
str=sprintf('Slice %d', k);
mtit(hFig, str);
k=k+1;
keyboard
end
function u=signal(a,b,file)
[fs,smplrt]=audioread(file);
u=fs(a:b,1);
end
where
something is wrong in updating the data because pressing CMD+Enter increases k by one but does not update the data. Sometimes (rarely), the data is once the next iteration.
something is wrong with while's condition because k can be bigger than nFrames. keyboard just keep asking for more inputs.
My mistake earlier in Error-Checking
I had earlier a problem where the closure of the window lead to the crash of the application. I include this here because I mentioned a problem about it in the comment of one answer. I avoid the problem now by
hFig=figure;
n=5;
k=1;
while k<nFrames
% for the case, the user closes the window but starts new iteration
if(not(ishandle(hFig)))
hFig=figure;
end
...
end
which creates a new Figure if the earlier was closed by the user.
I tried unsuccessfully putting hFig=figure; inside the while loop's if clause earlier to avoid repetition in the code.
Please, let me know if you know why you cannot have the handle hFig in the while loop's if clause.
How can you loop subplots with updated outputs in Matlab?

To stop the script waiting for an input from the user you should use input instead of keyboard.
Actually keyboard makes your script entering in a debug mode. It stops the executino of the script as (like a breakpoint) allowing the user to, for example, check the value of a variable.
You can modify your scripr as follows (modification are at the end of your script, identified by "UPDATED SECTION):
hFig=figure
nFrames=5;
k=1;
while k < nFrames
u=signal(1*k,100*k,'handel.wav'); % 100 length
subplot(2,2,1);
plot(u);
subplot(2,2,2);
plot(sin(u));
subplot(2,2,3);
plot(cos(u));
subplot(2,2,4);
plot(tan(u));
% not necessary but for heading of overal figure
%
% UPDATED SECTION
%
% Use the string "Press Enter for next slice\n" as the prompt for the
% call to "input"
%
% fprintf('Press Enter for next slice\n');
% str=sprintf('Slice %f', k);
% Use %d instead of "%f" to print integer data
str=sprintf('Slice %d', k);
mtit(hFig, str);
k=k+1;
% Use "input" instead of "keyboard"
% keyboard
input('Press Enter for next slice\n')
end
Hope this helps.
Qapla'

Related

Matlab code Sha-1 hashing password

clc;clear all;close all;
fileID = fopen('H:\dictionary.txt');
S = textscan(fileID,'%s','Delimiter','\n') ;
fclose(fileID);
S = S{1} ;
% remove empty cells
S = S(~cellfun('isempty',S));
n=length(S);
k=0;
for i=1:n
for j=1:n
k=k+1;
y(k,1)=strcat(S(i),S(j))
end
end
This is my code for sha-1 hashing. where i am getting problem in for loop to generate all possible combinations in line
y(k,1)=strcat(S(i),S(j)).
its running properly. but its taking too long. i have been running this code for 2 days still its not getting over as my dictionary contains over 5000 words. please suggest me some good idea to do faster and some better way to improve and crack it.
Since you did not provide some data to test the code, I created my own test data, which is a cell array containing 400 words:
% create cell array with a lot of words
S = repmat({'lalala','bebebebe','ccececeece','ddededde'},1,100);
Here is the code with some small changes but with huge impact on the performance.
Note that the variable 'y' is here named 'yy' so that you can just copy and paste the code to compare it with your existing code:
% Preallocate memory by specifying variable and cell size
yy = cell(n^2,1);
% Measure time
tic
k = 0;
for i=1:n
for j=1:n
k=k+1;
% Replace strcat() with [] and index cell content with S{i} instead
% of indexing the cell itself with S(i)
yy{k}=[S{i},S{j}];
end
end
% Stop and output time measurement
toc
With my examplary data, your code took 7.78s to run and the improved and proposed code took 0.23s on my computer.
I would recommend to read the Matlab docs about Preallocation.

GUI wait for user input and do something if time runs out

I am working with a script that takes user input. I want the user to answer on the input within 4 seconds otherwise the code shall do something (right now without using a GUI). What I have done so far is to start a tic and prompt a input testInput = input('Enter the number: '); Meanwhile the prompt is open (waiting for input) I am checking if time has not runed out:
elapsed_time = toc;
if elapsed_time > 4
%do something
end
To the problem:
From what I have learned, there's no way to programmatically terminate a running command in MATLAB, or even let the code do something while the prompt is open. Therefore I can not check if 4 sec has passed before the user inputs something. I've read (here) that this might be possible to solve by using a GUI. I have although no idea how to implement this, since I am totally new.
So, would this be possible with a GUI? Because with the command window it is not.
I would really appreciate to see how something simple like this could look like as a GUI (just something very simple, a window with a input box):
%Start a time ticker
tic;
testInput = input('Enter the number: ');
elapsed_time = toc;
if elapsed_time > 4
%do something
end
Here is a small example of a custom GUI where the user should enter a number before a maximum time is reached. Please read some about callbacks, handles, figure options and uicontrol to better understand it.
Note that you might need to do som more fault handling of the input string (check that number is valid)
function EnterNumber()
% Create figure
inDlg = figure('NumberTitle','off','MenuBar','none','ToolBar','none');
% Create timer, set it to run TimerFcn after 4 s
maxTime = 4;
tH = timer('TimerFcn', {#closeFig inDlg}, 'StartDelay', maxTime);
% Create text and input box for number in figure
uicontrol(inDlg,...
'Style','Text','FontSize',14, ...
'String',sprintf('Please enter a number within %d seconds:', maxTime),...
'Units','Normalized','Position',[0.1 0.6 0.8 0.2]);
editBox = uicontrol(inDlg,...
'Style','Edit','Units','Normalized','Position',[0.1 0.5 0.8 0.2], ...
'FontSize',14,'Callback',#returnEditValue);
% Start timer
start(tH);
% Set focus on the edit box so a number could be entered instantly
uicontrol(editBox)
% Wait for figure to be closed (in any way)
waitfor(inDlg)
fprintf('Moving on ...\n');
% Callback function to save number
function returnEditValue(hObject,~)
% Get the number
number = str2double(get(hObject,'String'));
% Example of how to display the number
fprintf('The entered number is %d\n', number);
% Example of saving the number to workspace
assignin('base','number', number);
% Close figure
close(get(hObject,'Parent'));
% Calback function for timer timeout
function closeFig(~,~,figH)
% If figure exist, close it
if ishandle(figH)
close(figH)
fprintf('Too slow!\n')
end

Overwritten data in Matlab loop

I've got the following code for a Push-button in a GUI, where it asks for a pair of coordinates (X,Y), saved in a vector Z.
I want it to save different .mat files with different names (I've achieved that already) for a specific number of iterations (3 in this case), clearing the edit boxes each time a value of Z is saved. The problem is that it overwrites the past values, keeping only the last one in the first file, and generating NaN's on the other ones.
Any help will be greatly appreciated.
function pushbutton1_Callback(hObject, eventdata, handles)
folder=pwd; %Current folder
x=str2double(get(handles.edit1,'String'));
y=str2double(get(handles.edit2,'String'));
z=[x y];
k=1;
ng=3;
while k<=ng
baseFileName=sprintf('data%02d.mat',k);
fullFileName=fullfile(folder,baseFileName);
save(fullFileName);
S.(sprintf('z%d',k))=z;
save(baseFileName,'-struct','S');
k=k+1;
if k<=ng;
set(handles.edit1,'String','')
set(handles.edit2,'String','')
x=str2double(get(handles.edit1,'String'));
y=str2double(get(handles.edit2,'String'));
z=[x y];
end
end

Order of graphics creation and data processing in MATLAB

I'm processing vast amount of data (>>100k lines) with variable step.
I would like to create figure and plot the processed data as they are counted (for termination of the running script when something goes wrong, or for impressing the "customers" with the fancy progress "animation").
Suppose we have `sourcefile.txt' with one column of positive numbers X(n) on row n and:
There is plenty of lines with X(n+1) < X(n),
X(n+N) > X(n); where N goes from thousands for small n to tens for large n.
I've thought of:
fID=fopen('sourcefile.txt');
figure;axes; % create figure
act='0';threshold=0;N=0;DATA=0;ii=0;
while ischar(act) % loop until end of file.
ii=ii+1;N=0;
while temp<threshold&&ischar(act) % loop until threshold is overflown (next step) or end-of-file is reached.
act=fgetl(fID);
temp=temp+str2double(act);
N=N+1;
end
line('xdata',ii,'ydata',temp/N,'Marker','o') % New point should appear
threshold=threshold+0.5; % Continue with new stopping rule.
end
The problem is that the loops are entered and processed and then figure is created. How can I force MATLAB to create a figure and then to calculate/update plotted data?
Try inserting drawnow after you draw the line using line. This will flush the graphics buffer and update your figure immediately. If you don't do this, your figure will appear blank until the loop finishes, and then the figure will appear with your objects that you added to the figure.
So to be specific with what I talked about:
fID=fopen('sourcefile.txt');
figure;axes; % create figure
act='0';threshold=0;N=0;DATA=0;ii=0;
while ischar(act) % loop until end of file.
ii=ii+1;N=0;
while temp<threshold&&ischar(act) % loop until threshold is overflown (next step) or end-of-file is reached.
act=fgetl(fID);
temp=temp+str2double(act);
N=N+1;
end
line('xdata',ii,'ydata',temp/N,'Marker','o') % New point should appear
%%%%%%%%%%%%// Change here
drawnow;
threshold=threshold+0.5; % Continue with new stopping rule.
end
Therefore, once you draw a line, the figure should immediately update itself and so for each iteration, the figure should update with a new line object.

Plot isn't entered in figure in loop in function

I'm trying to write a small function which should read a matrix of doubles, make a plot for all columns separately (and display the last row as line, as this is the mean) and save the plot.
All commands work when I tried them on the command line, but when I run them as a script it doesn't work. The plots are not entered in the figure (only ticks and labels are redrawn). When I copy the single commands in debug mode to the command line it works.
So what am I doing wrong here?
I'm loading a matrix 'corr' prior to this loop..
for i=1:30; % number of components
corr_fig(i)=figure;
hold;
plot(corr(1:length(sub),i));
line ([0 (length(sub))],[(corr(length(sub)+1)) (corr(length(sub)+1))], 'Color','m')
set(gca,'XTick',[1:(length(sub))])
set(gca,'XTickLabel',{sub{1:length(sub)}})
title(['Correlations for',num2str(i)])
saveas(corr_fig(i),['corrs_for_',num2str(i)],'fig');
hold off;
close all;
end
Throw in a 'drawnow' command in the loop. This flushes out the plotting buffer and forces MATLAB to create the figure, rather than trying to skip that step due to what the compiler sees happening in the loop.
For example, this:
for k = 1:100;
figure()
plot(rand(100, 1), rand(100, 1))
close all
end
draws nothing (never shows a figure window), but this:
for k = 1:100;
figure()
plot(rand(100, 1), rand(100, 1))
drawnow
close all
end
does what you would expect.
Thanks for all the answers! Figured it out on my own in the end. The code is fine, well mostly. I haven't assigned a proper variable name to the matrix I handed to the function and was not calling this name in the loop corectly (MAT.corr would have been it..) Now it's working.. Stupid me! Thanks nevertheless!