Add flexible legend in MATLAB - 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'

Related

Change the width of a subplot. There is no position property on the Line class

I have the following figure
that I created using the following code
%% figures
DateNumObs=datenum(table2array(ADCPCRUM2(1:1678,ColumnYear)),table2array(ADCPCRUM2(1:1678,ColumnMonth)),table2array(ADCPCRUM2(1:1678,ColumnDay)),table2array(ADCPCRUM2(1:1678,ColumnHour)),table2array(ADCPCRUM2(1:1678,ColumnMinutes)),table2array(ADCPCRUM2(1:1678,ColumnSeconds)));
Flipecart=permute(ecart(1:1677,:),[2,1]);
Flipecartreel=permute(ecartreel(1:1677,:),[2,1]);
bottomVel=min(min(min(Magnitude)),min(min(velocityModel*1000)));
topVel=max(max(max(Magnitude)),max(max(velocityModel*1000)));
bottomVer=min(min(Flipecart))
topVer=max(max(Flipecart))
figure
subplot(4,1,1);
FlipMag=permute(Magnitude,[2,1]);
[C,h] =contourf(DateNumObs,1:1:22,FlipMag);
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVel topVel])
c=colorbar;
c.Label.String = 'Horizontal velocity(mm/s)';
xlabel('Date');
ylabel('Depth(m from bottom)');
set(h,'LineColor','none')
title('Observation');
subplot(4,1,2);
[C,h] =contourf(DateNumObs(1:1677),1:1:22,MagMatrixH1*1000);
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVel topVel])
c=colorbar;
c.Label.String = 'Horizontal velocity(mm/s)';
xlabel('Date');
ylabel('Depth(m from bottom)');
set(h,'LineColor','none')
title('Model D1');
subplot(4,1,3)
% x0=10;
% y0=10;
% width=550;
% height=400
gcf=plot(DateNumObs(1:1677),Flipecart(10,:))
% set(gcf,'LineWidth',1,'position',[x0,y0,width,height]) % Part giving the error
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVer topVer])
subplot(4,1,4)
c=colorbar;
plot(DateNumObs(1:1677),Flipecartreel(10,:))
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVer topVer])
I am trying to got the normal plot to be the same size as the (blue) contourf plots by using the code which is commented in the code I posted. I got this code from https://nl.mathworks.com/matlabcentral/answers/65402-how-to-set-graph-size .
However, when I try to run it it gives me the following error:
Error using matlab.graphics.chart.primitive.Line/set
There is no position property on the Line class.
Error in StatisticsSOLA (line 315)
set(gcf,'LineWidth',1,'position',[x0,y0,width,height])
I also tried is it possible to change the height of a subplot? but I get the same error. How do I prevent this error and change the width of the bottom two figures?
You are trying to set the position of the axes and the linewidth of the line object in one go, but are not providing the correct handles. Furthermore, don't store the handles of the lines in gcf, since this is a reference to the currently active figure.
Instead you can do:
data = rand(100,200); % some data
fig = figure(1); clf;
% first subplot with colorbar
ax(1) = subplot(211);
imagesc(data)
c = colorbar;
% second subplot without colorbar
ax(2) = subplot(212);
p = plot(data(1,:))
% set height and width of second subplot
drawnow % needed to get right position value of ax(1) and ax(2)
ax_pos = [ax(2).Position(1:2) ax(1).Position(3:4)]; % keep ax(2)'s left and bottom position, and set same width and height as ax(1)
set(ax(2), 'Position', ax_pos)
Alternative
Sometimes it is easier to create colorbar in the second axes, and hide it. This way you don't have to set the positions of the axes yourself.
data = rand(100,200); % some data
fig = figure(1); clf;
% first subplot with colorbar
ax(1) = subplot(211);
imagesc(data)
c = colorbar;
% second subplot without colorbar
ax(2) = subplot(212);
p = plot(data(1,:))
c = colorbar; % draw useless colorbar,
c.Visible = 'off'; % and hide it
Figure should look the same:

Matlab: use plot and semilogy in same graph (Matlab 2014)

I want to use plot and semilog in the same graph so as to compare results. I get only the one waveform though using hold on function. What can I do ? I cant use yyaxis left cause my matlab is lower than 2016. Any help?
Here is my code:
figure
semilogy(VG, ID3)
hold on
plot(VG, ID3)
hold off
A possible solution to have both the linear and the semilog chart in the same graph could be to create two overlapping graphs:
on the first you can plot the data with the linear scale
on the second you can plot the data with the logarithmic scale either on the x or axis
The main steps are:
create a figure
create the first axes in the figure
set the color of the axes to the same color used for the data, this will help recognising the data
plot the data with plot
create the second axes in the figure and set its size equal to the one of the first axes (now the secon axes is the one "active")
move the X axis location to the top of the chart
move the Yaxis location to the right of the chart
plot the data with semilogy
set the color of the axes to the same color used for the data, this will help recognising the data
add the title, the legend and the x / y labels
Since we have changed the location of the X and Y axis of the second axes, we need to adjust the dimenisons of the figure and of the axes so thay fit toghter
Now you can fix the problem of the different grid of the two axes:
to do that, you can add a menu item to the menu bar (with the uimenu function) to toggle the grid
In the following, a possible implementation of the suggested approach.
Since you have not specified if you use R2014a or R014b, in the code below you can find both the way to set the properties of the figure and axes:
the "old" way: using get / set
the "new" one dot notation available from R2014b
(the last one is "commented")
% Define input data
x=linspace(0,30,30)
y=rand(30, 1);
% Cretate a Figure
f=figure('units','normalized')
% Create the first axes in the figure
ax1=axes
% Plot the data with "PLOT"
ph=plot(x,y,'r')
% Set the axis labeks
xlabel('X data')
ylabel('Y data, LIN mode')
% Get the position of the first axes
% % % % % % % % % % % % % % % % % % % % % % % % ax1_pos=ax1.Position
ax1_pos=get(ax1,'position')
% Set the color of the fist axes
% % % % % % % % % % % % % % % % % % % % % % % % ax1.XColor='r'
% % % % % % % % % % % % % % % % % % % % % % % % ax1.YColor='r'
set(ax1,'xcolor','r','ycolor','r')
% Add the second axes in the figure
ax2=axes('position',ax1_pos)
% Plot the data with SEMILOGY
slh=semilogy(x,y,'b')
% Set the ylabel
ylabel('Y data, LOG mode')
% Set the title of the chrt
title('Linear and Semilog Plot')
% Move the X axis location to the top of the chart
% % % % % % % % % % % % % % % % % % % % % % % % ax2.XAxisLocation='top'
set(ax2,'XAxisLocation','top')
% Move the XYaxis location to the right of the chart
% % % % % % % % % % % % % % % % % % % % % % % % ax2.YAxisLocation='right'
set(ax2,'YAxisLocation','right')
% Set the color of the second axes to transparent
% % % % % % % % % % % % % % % % % % % % % % % % % ax2.Color='none'
set(ax2,'color','none')
% Set the color of the second axes
% % % % % % % % % % % % % % % % % % % % % % % % % ax2.XColor='b'
% % % % % % % % % % % % % % % % % % % % % % % % % ax2.YColor='b'
set(ax2,'xcolor','b','ycolor','b')
% Add the lgend to the chart
legend([ph slh],'plot','semilogy','location','best')
% Adjust the size of the the first axes
% % % % % % % % % % % % % % % % % % % % % % % % ax1.Position=[ax1_pos(1) ax1_pos(2) ax1_pos(3)*.9 ax1_pos(4)*.9]
set(ax1,'position',[ax1_pos(1) ax1_pos(2) ax1_pos(3)*.9 ax1_pos(4)*.9])
% et the size of the second axes as per the first one
ax2.Position=ax1.Position
set(ax2,'position',[ax1_pos(1) ax1_pos(2) ax1_pos(3)*.9 ax1_pos(4)*.9])
% Adjust the size of the figure
% % % % % % % % % % % % % % % % % % % % % % % % % % % fp=f.Position
fp=get(f,'position')
% % % % % % % % % % % % % % % % % % % % % % % % % % % f.Position=[0.1,0.1,fp(3)*1.2,fp(4)*1.2]
set(f,'position',[0.1,0.1,fp(3)*1.2,fp(4)*1.2])
% Add the menu to manage the grid
mh=uimenu('Label','Grid manag.')
m1h=uimenu(mh,'Label','Linear Grid','callback', ...
'axes(ax1);grid;axes(ax2);if(strcmp(m1h.Checked,''off'')),m1h.Checked=''on'';else,m1h.Checked=''off'';end')
m2h=uimenu(mh,'Label','Log Grid','callback', ...
'axes(ax2);grid;if(strcmp(m2h.Checked,''off'')),m2h.Checked=''on'';else,m2h.Checked=''off'';end')
I often have to make figures comparing data in linear and log space. Stacking the plots using subplot() gives a nice visual. Example:
% set up dummy data that is evenly-space in logspace
x = 10.^((linspace(log10(.01), log10(10),20))');
y = rand(20, 1);
% finish setup
figure
subplot(2,1,1)
plot(x, y, 'DisplayName', 'MyData')
title('Plot with Linear Axes')
xlabel('X-Axis')
ylabel('Y-Axis')
grid on
set(legend, 'Location', 'best')
subplot(2,1,2)
semilogx(x, y, 'DisplayName', 'MyData')
title('Plot with LogX Axis')
xlabel('LogX-Axis')
ylabel('Y-Axis')
grid on
set(legend, 'Location', 'best')
The above produces this:

bin2mat running slow need a faster solution

I am using bin2mat function from matlab file exchange, for some reason it runs very slow. Is it possible to make it run faster or is there an alternative? I am trying: zC = bin2mat(s.X,s.Y,s.Z,xC,yC); I am not sure where it gets bogged down. I need to do this on point cloud data to calculate volume and such.
Here is the code:
function ZG = bin2mat(x,y,z,XI,YI,varargin)
% BIN2MAT - create a matrix from scattered data without interpolation
%
% ZG = BIN2MAT(X,Y,Z,XI,YI) - creates a grid from the data
% in the (usually) nonuniformily-spaced vectors (x,y,z)
% using grid-cell averaging (no interpolation). The grid
% dimensions are specified by the uniformily spaced vectors
% XI and YI (as produced by meshgrid).
%
% ZG = BIN2MAT(...,#FUN) - evaluates the function FUN for each
% cell in the specified grid (rather than using the default
% function, mean). If the function FUN returns non-scalar output,
% the output ZG will be a cell array.
%
% ZG = BIN2MAT(...,#FUN,ARG1,ARG2,...) provides aditional
% arguments which are passed to the function FUN.
%
% EXAMPLE
%
% %generate some scattered data
% [x,y,z]=peaks(150);
% ind=(rand(size(x))>0.9);
% xs=x(ind); ys=y(ind); zs=z(ind);
%
% %create a grid, use lower resolution if
% %no gaps are desired
% xi=min(xs):0.25:max(xs);
% yi=min(ys):0.25:max(ys);
% [XI,YI]=meshgrid(xi,yi);
%
% %calculate the mean and standard deviation
% %for each grid-cell using bin2mat
% Zm=bin2mat(xs,ys,zs,XI,YI); %mean
% Zs=bin2mat(xs,ys,zs,XI,YI,#std); %std
%
% %plot the results
% figure
% subplot(1,3,1);
% scatter(xs,ys,10,zs,'filled')
% axis image
% title('Scatter Data')
%
% subplot(1,3,2);
% pcolor(XI,YI,Zm)
% shading flat
% axis image
% title('Grid-cell Average')
%
% subplot(1,3,3);
% pcolor(XI,YI,Zs)
% shading flat
% axis image
% title('Grid-cell Std. Dev.')
%
% SEE also RESHAPE ACCUMARRAY FEVAL
% A. Stevens 3/10/2009
% astevens#usgs.gov
%check inputs
error(nargchk(5,inf,nargin,'struct'));
%make sure the vectors are column vectors
x = x(:);
y = y(:);
z = z(:);
if all(any(diff(cellfun(#length,{x,y,z}))));
error('Inputs x, y, and z must be the same size');
end
%process optional input
fun=#mean;
test=1;
if ~isempty(varargin)
fun=varargin{1};
if ~isa(fun,'function_handle');
fun=str2func(fun);
end
%test the function for non-scalar output
test = feval(fun,rand(5,1),varargin{2:end});
end
%grid nodes
xi=XI(1,:);
yi=YI(:,1);
[m,n]=size(XI);
%limit values to those within the specified grid
xmin=min(xi);
xmax=max(xi);
ymin=min(yi);
ymax=max(yi);
gind =(x>=xmin & x<=xmax & ...
y>=ymin & y<=ymax);
%find the indices for each x and y in the grid
[junk,xind] = histc(x(gind),xi);
[junk,yind] = histc(y(gind),yi);
%break the data into a cell for each grid node
blc_ind=accumarray([yind xind],z(gind),[m n],#(x){x},{NaN});
%evaluate the data in each grid using FUN
if numel(test)>1
ZG=cellfun(#(x)(feval(fun,x,varargin{2:end})),blc_ind,'uni',0);
else
ZG=cellfun(#(x)(feval(fun,x,varargin{2:end})),blc_ind);
end
It is slower on these two steps for one run it took:
ZG=cellfun(#(x)(feval(fun,x,varargin{2:end})),blc_ind); took 33 secs
blc_ind=accumarray([yind xind],z(gind),[m n],#(x){x},{NaN}); took 10 secs
You can change blc_ind = ... to
ZG=accumarray([yind xind],z(gind),[m n],#mean,NaN);
and delete other codes form here so the is no need to if numel(test)>1....

Why axes handle deleted in Matlab loop?

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

Handling multiple plots in MATLAB

I am using plot(X) whereX is an n-by-k matrix, which produces k plots with n points.
How do I show the legend for this plot? More importantly, is there an easy way to show checkboxes to show or not show certain plots?
I think you can find this section of Documentation useful.
GUI that Displays and Graphs Tabular Data
http://www.mathworks.com/help/techdoc/creating_guis/bropmbk-1.html
Please use this body for plot_callback function in tableplot.m file to get a dirty implementation of the flexible legend.
function plot_callback(hObject, eventdata, column)
% hObject Handle to Plot menu
% eventdata Not used
% column Number of column to plot or clear
colors = {'b','m','r'}; % Use consistent color for lines
colnames = get(htable, 'ColumnName');
colname = colnames{column};
lgidx = get(haxes, 'UserData');
if isempty(lgidx)
lgidx = false(size(colnames));
end
if get(hObject, 'Value')
% Turn off the advisory text; it never comes back
set(hprompt, 'Visible', 'off')
% Obtain the data for that column
ydata = get(htable, 'Data');
set(haxes, 'NextPlot', 'Add')
% Draw the line plot for column
hplot = plot(haxes, ydata(:,column),...
'DisplayName', colname,...
'Color', colors{column});
lgidx(column) = true;
else % Adding a line to the plot
% Find the lineseries object and delete it
hplot = findobj(haxes, 'DisplayName', colname);
lgidx(column) = false;
delete(hplot);
end
if any(lgidx)
legend(haxes, colnames{lgidx} );
else
legend(haxes, 'off')
end
set(haxes, 'UserData', lgidx);
end
An example:
x = cumsum(rand(100,3)-0.5); %# three series with 100 points each
h = plot(x);
legend(h, {'first' 'second' 'third'})