Matlab - No luck when using 'xtick' to change axis on graph - matlab

I have the following graph in Matlab:
I have tried using 'xTick' and 'yTick' to make the axis on each subplot the same, but it's not accomplishing what I would like it to. I also want the both axes of each subplot to share the same range so that I can easily compare the graphs. (i.e. ranging from 0 - 20, in y, and 0 - 400 in x).
I'm not sure how to change this.
My attempt is below. Does anyone know how to do this?
figure()
hold on
subplot (1,2,1);
% xlim([0 400]);
% ylim([0 25]);
graph_made = [num_calls_made];
plot (graph_made);
title('Number of calls made')
xlabel('ID Number of caller');
ylabel('Number of calls');
set(gca, 'XTick', [0:100:400]);
set(gca, 'YTick', [0:5:20]);
subplot (1,2,2);
graph_rec = [num_calls_received];
plot (graph_rec);
title('Number of calls received')
xlabel('ID Number of caller');
ylabel('Number of calls');
set(gca, 'XTick', [0:100:400]);
set(gca, 'YTick', [0:5:20]);
hold off

If you want the axes limits to stay linked as a user interactively zooms or pans, you can also use the linkaxes command...
subplot(1,2,1)
% your plotting code here...
ax = gca; %get the handle to the current axis
subplot(1,2,2)
% your plotting code here...
ax(end+1) = gca; %get the handle to the current axis
linkaxes(ax); %this will link both the x and y axes.

XTick and YTick only change where the labels on axes go, not the limits of the axes. To change those, you have to use axis (or xlim and ylim):
axis([0 400 0 20]) %// [xmin xmax ymin ymax]

Related

Secondary axes get displaced when resizing figure

I am trying to plot a Matlab (R2017a) figure (filled contour + colorbar) with two X axes, on the bottom and top of the graph, with the same scale but different tick marks and labels. Following the suggestions found here and here, I have achieved it, but when I try to resize the figure window manually or to print it setting certain proportions different from the default ones, e.g.:
set(gcf,'PaperUnits','centimeters','PaperPosition',[0 0 30 15])
print(gcf,'-dpng',path,'-r300')
the new axes get displaced:
I have reproduced my issue with the peaks example data from Matlab:
contourf(peaks)
ax1=gca;
colorbar
set(ax1,'box','off','color','none') % get rid of the box in order not to have duplicated tick marks
ax1_pos = ax1.Position; % position of first axes
ax2 = axes('Position',ax1_pos,... % set the new pair of axes
'XAxisLocation','top',...
'YAxisLocation','Right',...
'Color','none');
set(ax2, 'XLim', get(ax1, 'XLim'), 'YLim', get(ax1, 'YLim')); % set same limits as for ax1
set(ax2, 'XTick', 0:14:42, 'XTickLabels', {'a','a','a','a'},... % set new tick marks and labels for the top X axis.
'YTick', get(ax1, 'YTick'), 'YTickLabels', []);
Curiously enough, if I remove the colobar command and plot just the filled contour, the figure behaves correctly:
Does anyone know why is this happening (and how could it be solved)? I'm also open to achieve the two-X-axis plot by other means.
Your problem is that one axis has a colorbar and other does not, and even if you would add a colorbar to both axis, there can be quite a lot of automatic things going on that would resize your axis differently.
However, we can add an event listener and define a function to operate make both axis the same. The listener will make sure it catches the event (resizing) and that it calls the function we define. This is the code I made for that:
%% this creates the listener for change of size in the figure
f = figure('SizeChangedFcn',#(src,evn) fixaxis(src));
%% this is your code
contourf(peaks)
ax1=gca;
colorbar
set(ax1,'box','off','color','none') % get rid of the box in order not to have duplicated tick marks
ax1_pos = ax1.Position; % position of first axes
ax2 = axes('Position',ax1_pos,... % set the new pair of axes
'XAxisLocation','top',...
'YAxisLocation','Right',...
'Color','none');
set(ax2, 'XLim', get(ax1, 'XLim'), 'YLim', get(ax1, 'YLim')); % set same limits as for ax1
set(ax2, 'XTick', 0:14:42, 'XTickLabels', {'a','a','a','a'},... % set new tick marks and labels for the top X axis.
'YTick', get(ax1, 'YTick'), 'YTickLabels', []);
%% this will resize the axis if 2 of them exist
function fixaxis(src)
ax=findall(src,'Type','Axes');
if length(ax)==2
ax(2).Position=ax(1).Position;
end
end
Try also setting the 'PaperPositionMode' to 'auto':
set(gcf,'PaperUnits','centimeters','PaperPosition', [0 0 30 15], 'PaperPositionMode', 'auto');
% then print
print(gcf, '-dpng', 'myFile', '-r300')
Above command works for me. Produces following result:

Subplot with axis square

I am trying to use subplot with square axis but I failed, Below part of my code. I got Fig that has two plots but each one has different size
for i=1:N
figure
subplot (2,1,1);
plot (r(i,:),p(i,:));
grid on
set(gca, 'XTick', 0:0.5:4)
set(gca, 'YTick', -1:0.15:0.2)
axis square
xlim([0 4]);
ylim([-1 0.2]);
subplot (2,1,2);
[r,y]= meshgrid(linspace(0,4),linspace(0,4));
U =eval(U1);
[~,h] = contour(r,y,U,[0.001 0.01 0.05 0.08 0.1 0.2 0.25 0.3 0.4]);
set(h,'ShowText','on','TextStep',get(h,'LevelStep')*2)
colormap cool
grid on
axis square
hold on
xlim([0 4]);
ylim([0 4]);
plot (R,Y,'*r');
hold off
daspect([1 1 1]);
end
You should call axis square after changing the x and y limits of the axes after all plotting is done. If you change the xlims and ylims after calling axis square MATLAB will forget that you wanted it to be square. This is because there is no property of the axes that indicates that you want a square matrix, it's simply computed when you call axes square based upon the current xlims and ylims and the data aspect ratio.
subplot (2,1,1);
plot (r(i,:),p(i,:));
grid on
set(gca, 'XTick', 0:0.5:4)
set(gca, 'YTick', -1:0.15:0.2)
%// Do not call axis square here
xlim([0 4]);
ylim([-1 0.2]);
%// Call axis square here after you change the x/y limits
axis square

axes labels not displaying on 3d subplots

I have created 5 3D subplots which include a for loop. However, the labels of the X and Y axes are not displaying for some reason. I would appreciate any help on this matter. Below is the code.
On a separate note, any suggestions to make the figure more aesthetically pleasing would also be much appreciated.
% parameters
b=0.5;
O=27;
x=1:1:5;
% energies
e1 = 1:1:100;
e2 = 1:1:100;
% function
[e1,e2]=meshgrid(e1,e2);
hb=#(x)((O.^2)./factorial(O-x)).*...
exp(-b.*O.*e2);
hu=#(x)(O.^x).*...
exp(-b.*O.*e1);
p=#(x)hb(x)./(hb(x)+hu(x));
f=figure('visible','on')
clf(f);
for i=x
subplot(2,3,i);
mesh(e1,e2,p(i))
title(['X = ',int2str(i)], 'FontSize',12);
% log all axes
set(gca, 'XScale', 'log');
set(gca, 'YScale', 'log');
set(gca, 'ZScale', 'log');
axis([1 100 1 100 10^-300 1])
axis square
grid off
set(gca,'FontSize',10)
xlabel('e1')
ylabel('e2')
zlabel('p_{H}')
end
The issue seems to be something internal to MATLAB with how it is setting the position of the x and y labels when a 3D surface plot is used. This doesn't happen with a basic plot3 plot. If you do a get(get(gca,'Xlabel','Position')), you see that the z coordinate of the label is set to infinity, which I would guess is the problem.
I've come up with a less than ideal workaround, but it seems to accomplish the task:
% parameters
b=0.5;
O=27;
x=1:1:5;
% energies
e1 = 1:1:100;
e2 = 1:1:100;
% function
[e1,e2]=meshgrid(e1,e2);
hb=#(x)((O.^2)./factorial(O-x)).*...
exp(-b.*O.*e2);
hu=#(x)(O.^x).*...
exp(-b.*O.*e1);
p=#(x)hb(x)./(hb(x)+hu(x));
f=figure('visible','on');
clf(f);
for i=x
subplot(2,3,i);
mesh(e1,e2,p(i))
title(['X = ',int2str(i)], 'FontSize',12);
% log all axes
set(gca, 'XScale', 'log');
set(gca, 'YScale', 'log');
set(gca, 'ZScale', 'log');
axis([1 100 1 100 10^-300 1])
axis square
grid off
set(gca,'FontSize',10)
xlabel('e1')
ylabel('e2')
zlabel('p_{H}')
set(get(gca,'xlabel'),'Units','Normalized','Position',[0.75 0 0])
set(get(gca,'ylabel'),'Units','Normalized','Position',[0 0.05 0])
end
You'll probably have to manipulate those position vectors to get the labels exactly where you'd like.
I would also submit a bug report and see what MathWorks says.

Multiple y plots on same logarithmic scale for the x-axis

I am trying to plot 3 curves using the semilogx matlab function and add a fourth line to an additional y axis on the right. All of them should be plotted on the same logarithmic scale for the x-axis. The following code indicates the derived error; the x-axis is incorrect. The figure has to have a single x-axis mode of ticks, the logarithm one. How could this be fixed?
Plus, how can I add a legend for these 4 curves?
close all, clc
figure, semilogx([1:100:1000],[rand(1,10)],'bo-'),
xlabel('xlabel'),ylabel('ylabel'), hold on;
semilogx([1:100:1000], [rand(1,10)], 'ro-'), hold on,
semilogx([1:100:1000], [rand(1,10)], 'ko-'), hold off
legend('1','2','3','Location','Best')
ax1 = gca;
ax2 = axes('YAxisLocation','right',...
'Color' , 'none',...
'YColor', 'm');
linkaxes([ax1 ax2 ], 'x')
x4 = [1:100:1000];
y4 = [rand(1,10)*2];
line(x4, y4, 'color', 'm', 'Marker','x','LineStyle',':', 'parent',ax1)
ylabel('y2')
You can use plotyy function to plot two of your lines, one on the right and one on the left. You can then hold on and plot the remaining lines using semilogx.
plotyy([1:100:1000], [rand(1,10)], [1:100:1000], [rand(1,10)]*2, #semilogx);
hold on;
semilogx([1:100:1000], [rand(1,10)], 'ro-');
semilogx([1:100:1000], [rand(1,10)], 'mo-');
hold off;
legend('Line1','Line2','Line3','Line4','Location','Northwest')

Set equal limits for y-axis for two figures

How can I make the vertical axes of two plots equal?
For example:
a = [1 2 3; 21 1 3; 4 2 3; 4 5 6]
After plotting plot(a(1, :)) I get the following figure:
I have done some simple operations:
[U E V] = svd(a);
figure(2);
plot(U(1,:))
And get another figure:
How do I make the y-axis limits of both plots equal? Is it with the axes equal command?
UPDATE:
I've used the following commands:
figure (1)
ylim([0 3])
plot(a(1,:))
figure (2);
ylim([0 3])
plot(U(1,:))
But get the same result...
You can use ylim to force limits on the y-axis. For example:
figure(1)
%// Some plotting...
ylim([0 3])
figure(2)
%// Some more plotting
ylim([0 3])
This ensures that the y-axis is limited to the range [0, 3] in both plots. You can do the same for the limits of the x-axis with the command xlim.
Also note that if you want to set the limits for both axes at once, instead of using xlim and ylim (two commands), you can use axis (one command).
you can use the ylim or xlim functions.
You can clone the limits of one plot to another plot in this fashion:
h1 = figure;
% do first plot...
h2 = figure;
%do second plot...
% set first figure as active
figure(h1);
%get limits properties of the axes that are drawn in Figure 1
xL = get(gca, 'XLim');
yL = get(gca, 'YLim');
%switch to second figure and set it as active
figure(h2);
%set axis limit properties of Figure 2 to be the same as in Figure 1
set(gca, 'XLim', xL);
set(gca, 'YLim', yL);