Loop over subplots - matlab

Somehow, the title, xlabel, ylabel, ylim and xlim does not stay fixed in the script below, how do I fix this?
x = 0:0.01:1;
figure
p1 = subplot(2,1,1);
xlabel(p1, '$x$','Interpreter','LaTex', 'Fontsize', 16);
ylabel(p1, '$\sin(x+t)$','Interpreter','LaTex', 'Fontsize', 16);
title(p1, 'Sine','Interpreter','LaTex', 'Fontsize', 20);
ylim(p1, [-1 2])
xlim(p1, [0 1])
p2 = subplot(2,1,2);
xlabel(p2, '$x$','Interpreter','LaTex', 'Fontsize', 16);
ylabel(p2, '$\cos(x+t)$','Interpreter','LaTex', 'Fontsize', 16);
title(p2, 'Cosine','Interpreter','LaTex', 'Fontsize', 20);
ylim(p2, [-2 1])
xlim(p2, [0 1])
for t = 0:0.1:2
plot(p1, x, sin(x+t))
plot(p2, x, cos(x+t))
pause(0.1)
end

By default, since you haven't got hold on or hold all, when you replot in the loop everything is reset. Since you only want to change one set of values in each graph, you can use set rather than plot here to get around the issue.
First, after each subplot is called, plot the initial graph and take a handle for it:
p1 = subplot(2,1,1);
h1 = plot(p1,x,sin(x);
Then continue on setting up the labels, etc, as you already do.
In the loop, to replace the data in your existing graph:
for t = 0.1:0.1:2
set(h1,'Ydata',sin(x+t))
set(h2,'Ydata',cos(x+t))
pause(0.1)
end

Related

Is there a practical way to make xlim and ylim the same for multiple plots in MATLAB?

I've been trying to create a single figure of multiple plots in MATLAB. Even though I managed to include many features set for 4 plots, I couldn't set xlim and ylim just the same for both four of them. I had tried to use 'linkaxes' function in MATLAB but it didn't work as well. Is there any way to make it possible?
You can see my current plotting settings here in which I had tried to use hold on function to plot multiple figures at the same time, however, I cannot add xlim([-99 1000]) and ylim([45 70]) here, I need an x-axis as -99:10:1000 and y-axis as 45:5:70
Here you can see the current output of my plot in which xlim and ylim are not as what I intended:
P.S. The code in plain text:
nTime = 110;
axx = linspace(-99, 1000, nTime);
figure
hold on
plot(axx, allSubjsMeanH+50, 'linewidth', 4);
plot(axx, allSubjsMeanL+50, 'linewidth', 4);
xline(0,'--', 'linewidth', 1);
yline(50,'--', 'linewidth', 1);
plot(axx(significantH), -1, 'b*', 'linewidth', 1);
plot(axx(significantL), -3, 'r*', 'linewidth', 1);
xlabel('Time (ms)', 'FontSize', 13)
ylabel('Accuracy (%)', 'FontSize', 13)
title('Headline', 'FontSize', 13)
legend('H','L')
% Set figure position and size
rectFig = get(gcf,'position');
width=700;
height=300;
set(gcf,'position',[rectFig(1),rectFig(2),width,height],
'color', 'white');
% What I need to include but I couldn't:
xlim([-99 1000]);
ylim([45 70]);
% What I've tried to use:
linkaxes(axx, 'xlim', 'ylim')
P.S.2 When I run the code in this way, I can achieve getting xlim and ylim in a way I need, however, this time I'm losing the info related the plots of significantH and significantL. What I need is to get information related to 4 plots in the same figure with xlim and ylim are fixed.
figure
hold on
plot(axx, allSubjsMeanH+50, 'linewidth', 2);
plot(axx, allSubjsMeanL+50, 'linewidth', 2);
xline(0,'--', 'linewidth', 1);
yline(50,'--', 'linewidth', 1);
plot(axx(significantH), -1, 'b*');
plot(axx(significantL), -3, 'r*');
hold on
xlim([-99,1000]);
ylim([45,70]);
xlabel('Time (ms)', 'FontSize', 13)
ylabel('Accuracy (%)', 'FontSize', 13)
title('Headline', 'FontSize', 13)
legend('H','L')
Here you can see the output of it
The function linkaxes is used to link the x and/or y and/or z axes of different axes object (i.e. graph or plotting area). In your case, you have only one axes object. The function linkaxes is here without purpose.
From what I understand from your question you wish to use different y-axis for two of your four plots.
This can be achieved using the function yyaxis.
You must just add a yyaxis left or yyaxis right before your plot instruction wether you want to plot on the left or right axis.
The ylim function will apply to the current yaxis selected.
With subplot and axis I can get all 4 traces allSubjsMeanH+50 allSubjsMeanL+50 significantH significantL inside same figure :
clear all;close all;clc
nTime = 110;
axx = linspace(-99, 1000, nTime);
% simulating data
all_1=randi([50 70],1,nTime);
all_2=randi([50 70],1,nTime);
t1=randi([1 nTime],1,nTime);
t2=randi([1 nTime],1,nTime);
figure(1)
ax1=subplot(2,1,1)
hold(ax1,'on')
grid(ax1,'on')
plot(ax1,axx, all_1, 'linewidth', 4);
plot(ax1,axx, all_2, 'linewidth', 4);
xline(ax1,0,'--', 'linewidth', 1);
yline(ax1,50,'--', 'linewidth', 1);
xlabel(ax1,'Time (ms)', 'FontSize', 13)
ylabel(ax1,'Accuracy (%)', 'FontSize', 13)
title(ax1,'Headline1', 'FontSize', 13)
legend(ax1,'H','L')
ax2=subplot(2,1,2)
hold(ax2,'on')
grid(ax2,'on')
hp3=plot(ax2,axx(t1), -1*ones(1,numel(t1)), 'b*', 'linewidth', 1);
hp4=plot(ax2,axx(t2), -3*ones(1,numel(t2)), 'r*', 'linewidth', 1);
axis(ax2,[axx(1) axx(end) -5 5])
xlabel(ax2,'Time (ms)', 'FontSize', 13)
ylabel(ax2,'Accuracy (%)', 'FontSize', 13)
title(ax2,'Headline2', 'FontSize', 13)
legend(ax2,'H','L')
.
.

Multiple y axes in MATLAB (axis alignment issue when printing)

Here is a sample of a strange problem. I'd like to plot curves with multiple y axes and I use a fairly common method in MATLAB.
function plot_test()
clear;
savefile = 1;
scrsz = get(0,'ScreenSize');
figure('Position',[1 1 0.9 * scrsz(3) 0.9 * scrsz(4)]);
hold on;
box on;
x = 0:1:10;
h1 = plot(x, x.^2 , 'r', 'LineWidth', 2.5);
%Axis label
xlabel('XLabel', 'FontSize', 20, 'Interpreter', 'latex');
ylabel('YLabel', 'FontSize', 20, 'Interpreter', 'latex');
set(gca, 'FontSize', 20, 'LineWidth', 3);
ax1 = gca;
ax2 = axes('Position',get(ax1,'Position'),'XAxisLocation','top','YAxisLocation','right','Color','none','XColor','none','YColor','k');
linkaxes([ax1 ax2],'x');
hold on
box on;
h2 = plot(x, x, 'b', 'Parent', ax2, 'LineWidth', 2.5);
ylabel('Second YLabel', 'FontSize', 20, 'Interpreter', 'latex');
set(gca, 'FontSize', 20, 'LineWidth', 3);
hl=legend([h1 h2],{'First Line','Second Line'});
set(hl,'FontSize',15,'Location','Northwest', 'Orientation','Vertical')
%Save pdf
if savefile
% Backup previous settings
prePaperType = get(gcf,'PaperType');
prePaperUnits = get(gcf,'PaperUnits');
preUnits = get(gcf,'Units');
prePaperPosition = get(gcf,'PaperPosition');
prePaperSize = get(gcf,'PaperSize');
% Make changing paper type possible
set(gcf,'PaperType','<custom>');
% Set units to all be the same
set(gcf,'PaperUnits','inches');
set(gcf,'Units','inches');
% Save the pdf
print -dpdf Test.pdf;
% Restore the previous settings
set(gcf,'PaperType',prePaperType);
set(gcf,'PaperUnits',prePaperUnits);
set(gcf,'Units',preUnits);
set(gcf,'PaperPosition',prePaperPosition);
set(gcf,'PaperSize',prePaperSize);
end
The objective is to print a PDF of the figure and save it in the same folder as Test.pdf. This is accomplished but the axes are misaligned. On my Windows machine it looks horrible while on a Mac it looks almost okay (but if you look closely, the y-axes are indeed misaligned at the bottom).
This only happens when I use a second axis. Without that, all this runs perfectly. Any idea why?
Okay, so I found a way: The trick is to use plotyy. Sample code below
function plot_test2()
clear;
savefile = 1;
scrsz = get(0,'ScreenSize');
figure('Position',[1 1 0.9 * scrsz(3) 0.9 * scrsz(4)]);
hold on;
box on;
x=(0:1:10);
y1=x;
y2=x.^2;
[hAx, hLine1, hLine2] = plotyy(x,y1,x,y2);
%Axis label
xlabel(hAx(1),'XLabel', 'FontSize', 20, 'Interpreter', 'latex', 'Color', 'k');
ylabel(hAx(1),'YLabel', 'FontSize', 20, 'Interpreter', 'latex', 'Color', 'k');
ylabel(hAx(2),'Second YLabel', 'FontSize', 20, 'Interpreter', 'latex');
set(hAx,{'ycolor'},{'k';'k'})
set(hAx,{'FontSize'},{20;20}, {'LineWidth'}, {3;3})
set(hLine1,'LineWidth', 3)
set(hLine2,'LineWidth', 3)
set(hLine1,'Color', 'r')
set(hLine2,'Color', 'b')
hl=legend([hLine1 hLine2],{'First Line','Second Line'});
set(hl,'FontSize',15,'Location','Northwest', 'Orientation','Vertical')
%Save pdf
if savefile
% Backup previous settings
prePaperType = get(gcf,'PaperType');
prePaperUnits = get(gcf,'PaperUnits');
preUnits = get(gcf,'Units');
prePaperPosition = get(gcf,'PaperPosition');
prePaperSize = get(gcf,'PaperSize');
% Make changing paper type possible
set(gcf,'PaperType','<custom>');
% Set units to all be the same
set(gcf,'PaperUnits','inches');
set(gcf,'Units','inches');
% Save the pdf
print -dpdf Test.pdf;
% Restore the previous settings
set(gcf,'PaperType',prePaperType);
set(gcf,'PaperUnits',prePaperUnits);
set(gcf,'Units',preUnits);
set(gcf,'PaperPosition',prePaperPosition);
set(gcf,'PaperSize',prePaperSize);
end

Updating plot while maintaining axes rotations?

So far I have a 3d plot that updates in realtime during a Monto-Carlo simulation of a Kessel Run. I want the plot to be rotatable while updating, but with the rotate3d flag enabled, when I call drawnow after updating the plot data, it resets the axes rotation to the default orientation, canceling whatever the user changed it to. My relevant code is as follows:
s = scatter3(pg(:,1), pg(:,2), pg(:,3), 'O', 'filled');
set(s, 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'k');
hold on
p_x = curr_path(:,1);
p_y = curr_path(:,2);
p_z = curr_path(:,3);
p = plot3(p_x, p_y, p_z);
set(p, 'LineWidth', 2, 'Color', 'k');
p_x = longest.path(:,1);
p_y = longest.path(:,2);
p_z = longest.path(:,3);
p = plot3(p_x, p_y, p_z);
set(p, 'LineWidth', 2, 'Color', 'r');
p_x = shortest.path(:,1);
p_y = shortest.path(:,2);
p_z = shortest.path(:,3);
p = plot3(p_x, p_y, p_z);
set(p, 'LineWidth', 2, 'Color', 'b');
sample_str = sprintf('%d samples', sample);
short_str = sprintf('shortest: %g parsecs', shortest.dist);
long_str = sprintf('longest: %g parsecs', longest.dist);
title(sprintf('%s, %s, %s', sample_str, short_str, long_str));
xlim([-10 10]);
ylim([-10 10]);
zlim([-10 10]);
hold off
drawnow
This is executed every time I update the data being drawn on the plot. What can I add to ensure that the axes rotation is maintained during an update?
I hope I understood you problem right. Well, here goes!
I suppose the problem is related to using plot3, which apparently resets the view settings of the figure to their defaults.
I verified this with the following program:
figure;
x = randn(10,3);
p = plot3(x(:,1), x(:,2), x(:,3));
drawnow
pause; %// do rotations in the figure GUI, press a button when done
x = randn(10,3);
p = plot3(x(:,1), x(:,2), x(:,3)); %// rotations reset
drawnow;
pause
You can rotate the figure when the pause is active, but when the pause is released and the second call to plot3 made, the rotation settings are reset.
A solution which avoids the reset is to directly update the XData, YData, and ZData in the already drawn graphics object. This can be achieved as follows:
figure;
x = randn(10,3);
p = plot3(x(:,1), x(:,2), x(:,3));
drawnow
pause; %// do rotations in the figure GUI, press a button when done
x = randn(10,3);
set(p, 'XData', x(:,1), 'YData', x(:,2), 'ZData', x(:,3)); %// no reset!
drawnow;
pause
So whatever code you have, use the handle of the graphics object to directly update the line properties to avoid the reset.
I had the same problem, in Matlab 2015b you can solve it in this simple way.
[az,el] = view;
scatter3(x,y,z);
view(az,el);
drawnow

Missing vertical tick when using boxplot in matlab 2014a

I am using boxplot to draw my data using matlab 2014a. I used below code to plot my data and rotate my xlabel. However, it lost the vertical tick in figure. Could you see my expected figure (right side) and help me to add that tick in below code. Thanks
figure(1);
set(gcf,'color','w');
hold on;
rotation = 25;
fontSize = 12;
str={'Test 1','Test 2'};
x1 = normrnd(5,1,100,1);
x2 = normrnd(6,1,100,1);
ax1=subplot(1,2,1); boxplot([x1, x2]); title('This is result for above code','FontSize', fontSize);
% ylim([0 1]);
text_h = findobj(gca, 'Type', 'text');
for cnt = 1:length(text_h)
set(text_h(cnt), 'FontSize', fontSize,...
'Rotation', rotation, ...
'String', str{length(str)-cnt+1}, ...
'HorizontalAlignment', 'right')
end
set(ax1, 'fontsize', fontSize);
set(findobj(ax1,'Type','text'),'FontSize', fontSize);
ylabel('Temp')
boxplot doesn't automatically create xticks in Matlab R2014a and older versions (it does in R2015a, and probably in R2014b too).
You can add the xticks manually as follows:
set(ax1, 'xtick', [1 2])

How to get arrows on axes in MATLAB plot?

I want to plot something like this:
x = 0:0.01:10;
f = #(x) 50* 1.6.^(-x-5);
g = #(x) 50* 1.6.^(+x-10);
plot(x, f(x));
hold on
plot(x, g(x));
I can't manage to get axes similar to the ones in this figure:
I know I can remove the top and right lines like in this question, but I don't know how to get the arrows on the edges.
I don't need the additional annotations, but I would like to remove the ticks on the axes. I know how to do this when the axes are "normal", but I'm not sure if it must be done in another way when the axes are already manipulated.
Does anyone know how to do this?
Well, don't say I didn't warn you :)
% Some bogus functions
f = #(x) 50* 1.6.^(-x-5);
g = #(x) 50* 1.6.^(+x-10);
% Point where they meet
xE = 2.5;
yE = f(xE);
% Plot the bogus functions
figure(1), clf, hold on
x = 0:0.2:5;
plot(x,f(x),'r', x,g(x),'b', 'linewidth', 2)
% get rid of standard axes decorations
set(gca, 'Xtick', [], 'Ytick', [], 'box', 'off')
% Fix the axes sizes
axis([0 5 0 5])
% the equilibrium point
plot(xE, yE, 'k.', 'markersize', 20)
% the dashed lines
line([xE 0; xE xE], [0 yE; yE yE], 'linestyle', '--', 'color', 'k')
% the arrows
xO = 0.2;
yO = 0.1;
patch(...
[5-xO -yO; 5-xO +yO; 5.0 0.0], ...
[yO 5-xO; -yO 5-xO; 0 5], 'k', 'clipping', 'off')
% the squishy wiggly line pointing to the "equilibrium" text
h = #(x)0.5*(x+0.2) + 0.1*sin((x+0.2)*14);
x = 2.7:0.01:3.5;
plot(x, h(x), 'k', 'linewidth', 2)
% the static texts
text(xE-yO, -0.2, 'Q^*', 'fontweight', 'bold')
text(-2*yO, yE, 'P^*', 'fontweight', 'bold')
text(-2*yO, 4, 'Price', 'rotation', 90, 'fontsize', 14)
text( 4, -0.2, 'Quantity', 'fontsize', 14)
text( .5, 4.2, 'Demand', 'fontsize', 14, 'rotation', -55)
text( 4.0, 3.3, 'Supply', 'fontsize', 14, 'rotation', +55)
text( 3.6, 2.1, 'Equilibrium', 'fontsize', 14)
Result:
The symbolic math toolbox has provisions for making these arrows, but without that toolbox you are stuck with drawing the arrows yourself. The following code should be useful for this purpose:
% determine position of the axes
axp = get(gca,'Position');
% determine startpoint and endpoint for the arrows
xs=axp(1);
xe=axp(1)+axp(3)+0.04;
ys=axp(2);
ye=axp(2)+axp(4)+0.05;
% make the arrows
annotation('arrow', [xs xe],[ys ys]);
annotation('arrow', [xs xs],[ys ye]);
% remove old box and axes
box off
set(gca,'YTick',[])
set(gca,'XTick',[])
set(gca,'YColor',get(gca,'Color'))
set(gca,'XColor',get(gca,'Color'))
The only drawback is that for some figure window sizes you will have a 1-pixel white border below the arrows, and setting the LineWidth property of the axes to a ridiculous small value does not help.
But for printing, the small white border should not be relevant.