Why axes handle deleted in Matlab loop? - matlab

Code which tries to mimic the real dynamic condition
clear all; close all;
hFig2=figure('Units','inches', 'Name', 'Time');
hax2=axes(hFig2);
movegui(hFig2, 'southeast');
index=1;
while (index < 7);
hFig2=figure(hFig2);
u=0:0.01:1+index;
plot(hax2, u); % Give columns 1xXYZ to Matlab
hold on;
axis(hax2, 'xy');
axis(hax2, [0 (size(u,2)/1 - 0) min(u) max(u)]); % to maximise size
axis(hax2, 'off'); % no ticks
index=index+1;
pause(1);
hold off;
drawnow
end;
Logs 1 hax2 in more dynamic condition,
Logs 2 hax2 mostly in Code
%% Logs 1 in dynamic condition with failure output
% Failure in more dynamic conditions because axes get deleted for some reason
% hax2
%
% hax2 =
%
% handle to deleted Axes
%
%% Logs 2 mostly in Code condition and correct because
% hax2 =
%
% Axes with properties:
%
% XLim: [0 201]
% YLim: [0 2]
% XScale: 'linear'
% YScale: 'linear'
% GridLineStyle: '-'
% Position: [0.1300 0.1100 0.7750 0.8150]
% Units: 'normalized'
Error if failure in hax2 i.e. handle to deleted axes for some reason
%% Failure message
% Show all properties
%
% Warning: MATLAB has disabled some advanced graphics rendering features by switching to software OpenGL. For more information, click
% here.
% Error using plot
% Invalid handle.
%
% Error in test_invalid_handle (line 12)
% plot(hax2, u);
Some tentative proposals of solutions
Save the axes handle at the end of each loop; possible related thread Save axes handle when plotting In MATLAB
...
OS: Debian 8.5 64 bit
Matlab: 2016a
Hardware: Asus Zenbook UX303UA
Linux kernel: 4.6 of backports

When calling axes, the first input should be a parameter/value pair that specifies the parent. If you pass it a single handle graphics input it assumes that input is a handle to an axes
axes(hFig2)
% Error using axes
% Invalid axes handle
Or as you have it written
hax2 = axes(hFig2);
% Error using axes
% Too many output arguments.
Because you are passing an invalid axes handle to it, it doesn't properly assign the handle to a new axes to hax2. It is likely that your deleted hax2 that you're seeing is from a previous run of the script.
Instead, you'll want to use parameter/value pairs to specify the Parent property of the axes.
hax2 = axes('Parent', hFig2);
Also, I would remove the extraneous call to figure every time through the loop since you explicitly specify the parent object of each plot object

Related

Add flexible legend in MATLAB

I am trying to add a flexible legend (reduce the length of the line and suppress the unnecessary space between the line and the text) to my figure, I used the steps from another post : advanced plotting (legend manipulation) in Matlab, the code it work fine but when I try to show the figure in the full screen after the legend modification, Everything I have done is meaningless.
x = randn(6,20);
figure(2)
hax = gca;
plot(x(1,:),'--k','linewidth',1.5);
hold on;
plot(x(2,:),'b','linewidth',1.5);
% hold on;
plot(x(3,:),'g','linewidth',1.5);
% hold on;
plot(x(4,:),'r','linewidth',1.5);
% hold on;
plot(x(5,:),'c','linewidth',1.5);
% hold on;
plot(x(6,:),':r','linewidth',1.5);
ylabel('states','fontsize',14); xlabel('time(s)','fontsize',10);
%legend('True','SCKS(h1)','SCKS(h2)','SCKS(h3)','SCKS(h4)','DEM',14);
%
% New call "legend"
%
[leg_h,leg_item_h,~,~]=legend('True','SCKS(h1)','SCKS(h2)','SCKS(h3)','SCKS(h4)','DEM',14);
%
% legendshrink(0.8,[]);
%Fig_legend = legend('Taylor','Euler','LLscheme','LLscheme1');
%set(Fig_legend,'FontSize',7)
grid(hax,'on')
% axis(hax,'tight')
set(hax,'box','on','Layer','top');
set(hax,'tickdir','out')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GENERATION OF THE LEGEND %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Define a scale factor fot the lines
line_scale_factor=1.4;
% Define a scale factor fot the lines
text_scale_factor=1.35;
% Get the "Position" of the legend
orig_leg_pos=get(leg_h,'position')
% Get the number on objects in the legend
n_obj=length(leg_item_h);
% Extract the "Line" object
line_obj=leg_item_h(n_obj/3+1:2:n_obj);
% Get the "LineStyle" of each "Line" in the legend
l_style=get(line_obj,'LineStyle')
% Get the "Color" of each "Line" in the legend
l_col=cell2mat(get(line_obj,'color'))
% Get the "XData" and "YData" of the "Lines" in the legend
leg_x_data=cell2mat(get(line_obj,'xdata'))
leg_y_data=cell2mat(get(line_obj,'ydata'))
% Get the handle of the "Text" of the items in the legend
leg_t=leg_item_h(1:n_obj/3)
% Get the "Text" of the items in the legend
str=get(leg_t,'string')
% Get the "Position" of each "Text" item in the legend
tx=cell2mat(get(leg_t,'position'))
% Delete the original legend
delete(leg_h)
% Create an axes with the same position and size of the original legend
ax=axes('position',orig_leg_pos,'xlim',[0 1],'ylim',[0 1], ...
'xtick',[],'ytick',[],'box','on')
hold on
% Add the legend items to the axes
for i=1:n_obj/3
% Add the lines with the original settings (color, style, ...)
plot([leg_x_data(i,1) leg_x_data(i,2)/line_scale_factor],leg_y_data(i,:),'color',l_col(i,:), ...
'linestyle',l_style{i}, ...
'linewidth',1.4)
% Add the text
th(i,:)=text(leg_x_data(i,2)/text_scale_factor,tx(i,2),0,str{i},'fontsize',9, ...
'unit','normalized')
end
% Get the maximun extent of the lagend "Text"
tx_max_ext=max(reshape([th(:).Extent],4,6)');
% Evaluate the axis scaling factor
tx_r_1=tx_max_ext(3)+leg_x_data(i,2)/line_scale_factor
% Get the axes position
axp=ax.Position
% Resize the axes width
ax.Position=[axp(1) axp(2) axp(3)*tx_r_1 axp(4)]
You can achieve your goal by moving the section of the above code that create the "new legend" into a ResizeFcn of the figure.
This allow adequating the size of the axes based legend each time the size of the figure changes.
To do so, you have to modify your code this way:
1) assign a tag to the figure, This will be used in the ResizeFcn to access to the figure:
cf=figure('tag','res_leg')
2) use guidata to store the original legend handles into the figure object
% Set in the FIGURE GUIDATA the legend handles
my_guidata=guidata(cf)
my_guidata.leg_h=leg_h;
my_guidata.leg_item_h=leg_item_h
% Store the GUIDATA data
guidata(cf,my_guidata)
3) Assign the ResizeFcn to the figure
set(cf,'ResizeFcn',['doResizeFcn(''' get(gcf,'tag') ''')'])
4) Define the ResizeFcn
just move the code you have now in the section in the section % GENERATION OF THE LEGEND % in a function named as the ResizeFcn (in this case doResizeFcn)
Make the following update to the above mentioned code (in the order they are in in the code):
4.1) Get the handle of the figure
4.2) Retrie the figure data using guidata
4.3) Check if the figure already contains the axes used in place of the legend; if so, delete it
4.4) Retrie the original legend data using guidata
4.5) Store in the figure guidata the handle of the axes created to replace the original legend
4.6) Store the figure's guidata
In the following the whole updated code - the above described steps are marked in the code as
%%%%%%%%%%%%
% STEP 4.1 %
%%%%%%%%%%%%
Original code for the plotting
x = randn(6,20);
%%%%%%%%%%
% STEP 1 %
%%%%%%%%%%
% Create the FIGURE and assign a TAG to it (to be used by FINDOBJ)
cf=figure('tag','res_leg')
hax = gca;
plot(x(1,:),'--k','linewidth',1.5);
hold on;
plot(x(2,:),'b','linewidth',1.5);
% hold on;
plot(x(3,:),'g','linewidth',1.5);
% hold on;
plot(x(4,:),'r','linewidth',1.5);
% hold on;
plot(x(5,:),'c','linewidth',1.5);
% hold on;
plot(x(6,:),':r','linewidth',1.5);
ylabel('states','fontsize',14); xlabel('time(s)','fontsize',10);
%legend('True','SCKS(h1)','SCKS(h2)','SCKS(h3)','SCKS(h4)','DEM',14);
%
% New call "legend"
%
[leg_h,leg_item_h,~,~]=legend('True','SCKS(h1)','SCKS(h2)','SCKS(h3)','SCKS(h4)','DEM',14);
%
% legendshrink(0.8,[]);
%Fig_legend = legend('Taylor','Euler','LLscheme','LLscheme1');
%set(Fig_legend,'FontSize',7)
grid(hax,'on')
% axis(hax,'tight')
set(hax,'box','on','Layer','top');
set(hax,'tickdir','out')
%%%%%%%%%%
% STEP 2 %
%%%%%%%%%%
% Set in the FIGURE GUIDATA the legend handles
my_guidata=guidata(cf)
my_guidata.leg_h=leg_h;
my_guidata.leg_item_h=leg_item_h
% Store the GUIDATA data
%%%%%%%%%%
% STEP 3 %
%%%%%%%%%%
guidata(cf,my_guidata)
%%%%%%%%%%
% STEP 4 %
%%%%%%%%%%
% Assign a RESIZE function the the figure
set(cf,'ResizeFcn',['doResizeFcn(''' get(gcf,'tag') ''')'])
Figure's ResizeFnc
function doResizeFcn(str)
%%%%%%%%%%%%
% STEP 4.1 %
%%%%%%%%%%%%
% Get the handle of the calling FIGURE
curr_fig=findobj('tag',str);
%%%%%%%%%%%%
% STEP 4.2 %
%%%%%%%%%%%%
% Retrieve the GUIDATA
my_guidata=guidata(curr_fig)
%%%%%%%%%%%%
% STEP 4.3 %
%%%%%%%%%%%%
% Check if the RESIZE function has been already called
if(isfield(my_guidata,'ax'))
% if so, delete the previously created axes (used in place of the
% legend)
delete(my_guidata.ax)
end
%%%%%%%%%%%%
% STEP 4.4 %
%%%%%%%%%%%%
% Get the old legend handles to retrieve the original legend data
leg_h=my_guidata.leg_h;
leg_item_h=my_guidata.leg_item_h
line_scale_factor=1.4;
% Define a scale factor fot the lines
text_scale_factor=1.35;
% Get the "Position" of the legend
orig_leg_pos=get(leg_h,'position')
% Get the number on objects in the legend
n_obj=length(leg_item_h);
% Extract the "Line" object
line_obj=leg_item_h(n_obj/3+1:2:n_obj);
% Get the "LineStyle" of each "Line" in the legend
l_style=get(line_obj,'LineStyle')
% Get the "Color" of each "Line" in the legend
l_col=cell2mat(get(line_obj,'color'))
% Get the "XData" and "YData" of the "Lines" in the legend
leg_x_data=cell2mat(get(line_obj,'xdata'))
leg_y_data=cell2mat(get(line_obj,'ydata'))
% Get the handle of the "Text" of the items in the legend
leg_t=leg_item_h(1:n_obj/3)
% Get the "Text" of the items in the legend
str=get(leg_t,'string')
% Get the "Position" of each "Text" item in the legend
tx=cell2mat(get(leg_t,'position'))
% Delete the original legend
% % % delete(leg_h)
leg_h.Visible='off'
% Create an axes with the same position and size of the original legend
ax=axes('position',orig_leg_pos,'xlim',[0 1],'ylim',[0 1], ...
'xtick',[],'ytick',[],'box','on')
%%%%%%%%%%%%
% STEP 4.5 %
%%%%%%%%%%%%
% Store in the FIGURE GUIDATA the axes handle
my_guidata.ax=ax;
%%%%%%%%%%%%
% STEP 4.6 %
%%%%%%%%%%%%
% Store the FIGURE GUIDATA
guidata(curr_fig,my_guidata)
hold on
% Add the legend items to the axes
for i=1:n_obj/3
% Add the lines with the original settings (color, style, ...)
plot([leg_x_data(i,1) leg_x_data(i,2)/line_scale_factor],leg_y_data(i,:),'color',l_col(i,:), ...
'linestyle',l_style{i}, ...
'linewidth',1.4)
% Add the text
th(i,:)=text(leg_x_data(i,2)/text_scale_factor,tx(i,2),0,str{i},'fontsize',9, ...
'unit','normalized')
end
% Get the maximun extent of the lagend "Text"
tx_max_ext=max(reshape([th(:).Extent],4,6)');
% Evaluate the axis scaling factor
tx_r_1=tx_max_ext(3)+leg_x_data(i,2)/line_scale_factor
% Get the axes position
axp=ax.Position
% Resize the axes width
ax.Position=[axp(1) axp(2) axp(3)*tx_r_1 axp(4)]
end
Hope this helps,
Qapla'

How to delete previous points while plotting?

I am plotting live data: for the plotting, I am using the line function, which improved the plotting performance a lot compared when using the plot function. Still, the plot gets slower with time. I realized that the sample points that I am creating are plotted, but even when they are not visible later the still remain in the plot. Could this cause any performance degradation?
I just want to see the sample points of the current three seconds, if use clf or cla function, just see very small part of the signal, which is not helpful for me. Do you have any suggestions?
%% opening function:
handles.figureHandle=figure;
guidata(hObject, handles);
t=1/200; %sample rate 5ms
%% button function:
if 40< newSamples
figure(handles.figureHandle)
t = max(t) + (1:size(sample,1)) * 1/200;
for x=1:8
subplot(8,8,x);
hold on
line('XDATA',t,'YDATA',sample(:,x),'MarkerSize', 1,'Color','r');
ylim([0 1024]);
xlim([max(t)-1 max(t)+2]);
hold off
end
drawnow ;
end
Update
%% opening function
sample=[];
t=[];
handles.figureHandle
for i=1:8
subplot(2,2,i);
hold on
h=line(t,sample,'MarkerSize', 1,'Color','r');
% ylim([0 1024]);
% xlim([max(t)-1 max(t)+2]);
hold off
end
t=1/200;
%% button function
figure(handles.figureHandle)
t = get(gca, 'XData');
sample = get(gca, 'YData');
t = max(t) + (1:size(sample,1)) * 1/200;
for x=1:8
set(h,'XData',t,'YData',sample(:,x));
end

plot data in real time using tcpip connection with matlab

I connect my iPhone and matlab with the tcpip function.
I need to plot the data in real time (and before make some calculations with the data).
I used real_time_data_stream_plotting.m which I found in internet.
%% Real Time Data Stream Plotting Example
function real_time_data_stream_plotting
%%
% This example demonstrates how to automatically read a set number of data bytes as and
% when they are available. This MATLAB(R) script also generates a real time plot of streaming
% data collected from the TCPIP server.
%
% The script may be updated to use any instrument/device/TCPIP server
% to collect real time data. You may need to update the IP address and
% port.
%
% To generate a report of this entire script, you may use the PUBLISH
% command at the MATLAB(R) command line as follows:
%
% publish(real_time_data_plot);
% Author: Ankit Desai
% Copyright 2010 - The MathWorks, Inc.
%% Create the interface object
% Create a TCPIP object listening to port 19 (Character Generator).
%
% *Note* : To enable character generator service at port 19 on a Windows platform, enable:
%
% Control Panel > Add Remove Programs > Add/Remove Windows Component > Networking Services
%
interfaceObject = tcpip('192.168.1.111',52928);
%%
% Setup a figure window and define a callback function for close operation
figureHandle = figure('NumberTitle','off',...
'Name','Live Data Stream Plot',...
'Color',[0 0 0],...
'CloseRequestFcn',{#localCloseFigure,interfaceObject});
%%
% Setup the axes
axesHandle = axes('Parent',figureHandle,...
'YGrid','on',...
'YColor',[0.9725 0.9725 0.9725],...
'XGrid','on',...
'XColor',[0.9725 0.9725 0.9725],...
'Color',[0 0 0]);
xlabel(axesHandle,'Number of Samples');
ylabel(axesHandle,'Value');
%%
% Initialize the plot and hold the settings on
hold on;
plotHandle = plot(axesHandle,4,'-y','LineWidth',1);
%% Setup interface object to read chunks of data
% Set the number of bytes to read at a time
bytesToRead = 500;
%%
% Define a callback function to be executed when desired number of bytes
% are available in the input buffer
interfaceObject.BytesAvailableFcn = {#localReadAndPlot,plotHandle,bytesToRead};
interfaceObject.BytesAvailableFcnMode = 'byte';
interfaceObject.BytesAvailableFcnCount = bytesToRead;
%%
% Open the interface object
fopen(interfaceObject);
pause(3);
snapnow;
%% Implement the bytes available callback
function localReadAndPlot(interfaceObject,~,figureHandle,bytesToRead)
%%
% Read the desired number of data bytes
data = fread(interfaceObject,bytesToRead);
%%
% Update the plot
set(figureHandle,'Ydata',data);
%% Implement the close figure callback
function localCloseFigure(figureHandle,~,interfaceObject)
%%
% Clean up the interface object
fclose(interfaceObject);
delete(interfaceObject);
clear interfaceObject;
%%
% Close the figure window
delete(figureHandle);
My problem is that I have a plot in real time but I have no idea which data I am plotting. I know that the data that arrived from the iPhone are a matrix with 62 column (if I export the data from the iPhone directly I get a .csv file of 62 columns).
How can I choose with column I plot ?
Thank you very much!
Here would be my take on indexing the data only for the required column:
function real_time_data_stream_plotting()
% These can be very well arguments for the function
FRAME_SIZE = 62; % This many columns (each columns is one byte)
FRAME_COUNT = 500; % This much data to plot at once
DATA_COLUMN = 3 % Position of the plotted column
% Create connection
conn = tcpip('192.168.1.111', 52928);
% Set-up graphics
hf = figure( ...
'NumberTitle', 'off', ...
'Name', 'Live Data Stream Plot', ...
'Color', [0 0 0], ...
'CloseRequestFcn', {#localCloseFigure,conn} ...
);
ha = axes( ...
'Parent', hf,...
'YGrid', 'on', ...
'YColor', [0.9725 0.9725 0.9725], ...
'XGrid', 'on', ...
'XColor', [0.9725 0.9725 0.9725], ...
'Color', [0 0 0] ...
);
hold(ha, 'on');
xlabel(ha,'Number of Samples');
ylabel(ha,'Value');
hl = plot(ha, 4, '-r', 'LineWidth', 1);
% Set-up connection callback
conn.BytesAvailableFcn = {#update_plot, hl, FRAME_SIZE, FRAME_COUNT, DATA_COLUMN};
conn.BytesAvailableFcnMode = 'byte';
conn.BytesAvailableFcnCount = FRAME_SIZE * FRAME_COUNT;
% Open connection and exit
fopen(conn);
pause(3);
snapnow;
end
% -------- Local Functions --------
function update_plot(conn, ~, hl, frame_size, frame_count, data_column)
data = fread(conn, frame_count*frame_size);
data = data(data_column + frame_size*(0:frame_count-1));
set(hl, 'YData', data);
end
function clean_up_on_close(hf, ~, conn)
fclose(conn);
delete(conn);
clear conn;
delete(hf);
end
However, I don't feel comfortable posting code based on on copyrighted work...

error in using fftoneside

Hi I'm trying to calculate mfcc for which i'm windowing. I have seen this one post I'm getting error in fftOneSide.
my code is
waveFile='test_preEmphasis.wav';
[y, fs]=wavread(waveFile);
n=512;
t=(1:n)'/fs;
startIndex=30418;
endIndex=startIndex+n-1;
original=y(startIndex:endIndex);
windowed=original.*hamming(n);
[mag1, phase1, freq1]=fftOneSide(original, fs);
[mag2, phase2, freq2]=fftOneSide(windowed, fs);
subplot(3,2,1); plot(original); grid on; axis([-inf inf -1 1]);
title('Original signal');
subplot(3,2,2); plot(windowed); grid on; axis([-inf inf -1 1]);
title('Windowedsignal');
subplot(3,2,3); plot(freq1, mag1); grid on;
title('Energy spectrum (linear scale)');
subplot(3,2,4); plot(freq2, mag2); grid on;
title('Energy spectrum (linear scale)');
subplot(3,2,5); plot(freq1, 20*log(mag1)); grid on;
axis([-inf inf -80 120]); title('Energy spectrum (db)');
subplot(3,2,6); plot(freq2, 20*log(mag2)); grid on; axis([-inf inf -80 120]);
title('Energy spectrum (db)');
the error i'm getting is
??? Undefined function or method 'fftOneSide' for input arguments of type 'double'.
any help is appreciated
thanks
This is a really old post, it'd be neat if someone still cared. I just provided what I believe to be the answer in the recent post below, which I arrived at after a fair bit of frustration: Undefined function 'fftOneSide' for input arguments of type 'double'.
It should be noted here there's a call to a file, which I'm not sure if the author had originally or not. I suspect all the problems are related to a similarly named file in the sourcecode.
If you look at my discussion in the other post, within the function definition there is a call to a method demo with a file - which isn't present if you just have the function definition, not the original file. Calling [mag1, phase1, freq1]=fftOneSide(original, fs,1), after you comment out the first line if nargin <1... and the demo routine worked fine on my machine with the code which I'll show below. Having the third argument equal to 1 guarantees that the code will run the print routines, which is important.
In case the other thread is closed, I just want to show the output, when the input is manually defined, and I call [mag1, phase1, freq1]=fftOneSide(original, fs,1) on the properly edited method, with the inputs as in the original post shown below (notice the call is to original in fftOneSide..in the other post it was like this as well.. I believe the call was was meant to be instead for windowed, but I don't have the signals toolbox with hamming anyways):
fs=8000;
t=(1:512)'/fs; %'// <-- prevents string markdown
f=306.396;
original=sin(2*pi*f*t)+0.2*randn(length(t),1);
% windowed=original.*hamming(length(t)); % defined in other post
[mag1,phase1,freq1]=fftOneSide(original,fs); % I call fftOneSide(original,fs,1);
The output is as follows (source code below!)
Anyways, here's the source code in case anyone wants to use this function
function [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs, plotOpt)
% fftOneSide: One-sided FFT for real signals
% Usage: [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs)
%
% For example:
% [y, fs]=wavread('welcome.wav');
% frameSize=512;
% startIndex=2047;
% signal=y(startIndex:startIndex+frameSize+1);
% signal=signal.*hamming(length(signal));
% plotOpt=1;
% [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs, plotOpt);
% Roger Jang, 20060411, 20070506
if nargin<1, selfdemo; return; end %=== (MathBio: Comment this out!)
if nargin<2, fs=1; end
if nargin<3, plotOpt=0; end
N = length(signal); % Signal length
freqStep = fs/N; % Frequency resolution
time = (0:N-1)/fs; % Time vector
z = fft(signal); % Spectrum
freq = freqStep*(0:N/2); % Frequency vector
z = z(1:length(freq)); % One side
z(2:end-1)=2*z(2:end-1); % Assuming N is even, symmetric data is multiplied by 2
magSpec=abs(z); % Magnitude spectrum
phaseSpec=unwrap(angle(z)); % Phase spectrum
powerSpecInDb=20*log(magSpec+realmin); % Power in db
if plotOpt
% ====== Plot time-domain signals
subplot(3,1,1);
plot(time, signal, '.-');
title(sprintf('Input signals (fs=%d)', fs));
xlabel('Time (seconds)'); ylabel('Amplitude'); axis tight
% ====== Plot spectral power
subplot(3,1,2);
plot(freq, powerSpecInDb, '.-'); grid on
title('Power spectrum');
xlabel('Frequency (Hz)'); ylabel('Power (db)'); axis tight
% ====== Plot phase
subplot(3,1,3);
plot(freq, phaseSpec, '.-'); grid on
title('Phase');
xlabel('Frequency (Hz)'); ylabel('Phase (Radian)'); axis tight
end
% ====== Self demo (MathBio: Comment all of this out! )
function selfdemo
[y, fs]=wavread('welcome.wav');
frameSize=512;
startIndex=2047;
signal=y(startIndex:startIndex+frameSize+1);
signal=signal.*hamming(length(signal));
[magSpec, phaseSpec, freq, powerSpecInDb]=feval(mfilename, signal, fs, 1);

Plotting onto specified axes in Matlab GUIDE

I have the following code for a pushbutton using Matlab GUIDE.It is supposed to plot a rotating arrow which rotates to the angles specified by theta 1 and theta 2.
function start_pushbutton_callback_Callback(hObject, eventdata, handles)
% hObject handle to start_pushbutton_callback (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles = guidata(hObject);
theta1 = handles.xy_angle;
theta2 = handles.yz_angle;
delay = handles.speed;
axes(handles.axes_turntable_xy);
R= 1; %Radius of the turntable
E=[0;0;0];
C=[-2;0;0];% points on the X axis
D=[2;0;0]; % points on the X axis
G=[0;2;0]; % points on the Y axis
H=[0;-2;0];% points on the Y axis
for th =1:1:theta1
clf;
Radius =1;
[x,y,z] = cylinder(Radius,200);
plot(x(1,:),y(1,:))
axis equal
L1= [R*cosd(th);R*sind(th);0];
drawvector(E,L1); % call the drawvector function, as previously
line([C(1),D(1)],[C(2),D(2)]);
line([G(1),H(1)],[G(2),H(2)]);
axis([-2 2 -2 2]);
grid on;
pause(delay);
end;
axes(handles.axes_turntable_yz) ;
R= 1; %Radius of the turntable
E=[0;0;0];
C=[-2;0;0];% points on the X axis
D=[2;0;0]; % points on the X axis
G=[0;2;0]; % points on the Y axis
H=[0;-2;0];% points on the Y axis
for th =1:1:theta2;
clf;
Radius = 1;
[x,y,z] = cylinder(Radius,200);
plot(x(1,:),y(1,:))
axis equal
L1= [R*cosd(th);R*sind(th);0];
drawvector(E,L1); % call the drawvector function
line([C(1),D(1)],[C(2),D(2)]);
line([G(1),H(1)],[G(2),H(2)]);
axis([-2 2 -2 2]);
grid on;
pause(delay);
end
However, I am facing two problems with this code:
1) It simply plots onto a new matlab figure instead of plotting it on axes_turntable_xy-
2) It displays the following error afer executing till the line axes(handles.axes_turntable_yz). The error is as follows:
Error using axes
Invalid object handle
Error in turntable_interface_model>start_pushbutton_callback_Callback (line 235)
axes(handles.axes_turntable_yz) ;
Error in gui_mainfcn (line 96)
feval(varargin{:});
Error in turntable_interface_model (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in
#(hObject,eventdata)turntable_interface_model('start_pushbutton_callback_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating uicontrol Callback
Can anyone help with this?
Okay, I debugged the code and this was the problematic line in the above code:
for th =1:1:theta1
clf;
Radius =1;
[x,y,z] = cylinder(Radius,200);
The working code is:
for th1 =1:1:theta1
cla(handles.axes_turntable_xy); %clears the figure handles.axes_turntable_xy
Radius =1;
[x,y,z] = cylinder(Radius,200);
This clears the figure I am plotting in in Matlab, not some unspecified figure! Although it's still hard to understand why Matlab was plotting these commands in a new figure inspite of making axes.turntable_xy the current axes.