consistent axis scale in matlab plot - matlab

I am using matlab for plotting scatter data. I want that the figure be in the range of [0 68] for X and [0 100] for Y, but when I use the following command, the X and Y axis are not consistent. For example, I expect the vertical axis to be longer than horizontal, while matlab give me something else. Have I missed something in the figure setting?
figure, axis([0 68 0 100]); box off , scatter(y,x,100,val,'filled'); box on;

It seems to be a matter of the order of commands.
x = 1:60;
y = 1/3.*x;
plot(x,y)
grid on
axis([0 60 0 20])
axis equal
will return
what you don't want, as it screws up your limits.
So rather use:
axis equal
axis([0 60 0 20])
and it is alright:

Related

Double x and y-axis on imagesc and surf plot in Matlab

I want to put two values on the x-axis and y-axis of a imagesc and surf plot. Both plots plot the same values but the first is 2D and the second 3D.
The arrays that I want to put on the x-axis and y-axis have the same length and are both interesting to display in a single plot because they are related to each other.
So the x-axis and y-axis should look like the example solution in this post (matlab multiple x axis one below another).
In case of a imagesc plot a double x-axis is not that difficult with the code of johan of the example solution and some random data.
Z = rand(20,30);
Y = 32.*(1:size(Z,1));
X = 1:size(Z,2);
scale_factor_xaxis=10;
scale_factor_yaxis=100;
figure(1)
imagesc(X,Y,Z)
set(gca,'XDir','normal','YDir','normal');
title('title')
xlabel('first x label')
ylabel('first y label')
first_axis = gca;
sqzx = 0.15; %// distance to squeeze the first x-axis plot
sqzy = 0.15; %// distance to squeeze the first y-axis plot
set(first_axis, 'Position', get(first_axis, 'Position') + [0 sqzx 0 -sqzx ]);
ax2 = axes('Position', get(first_axis, 'Position') .* [1 1 1 1e-12] - [0 sqzx 0 0],'Color','none');
xlim(get(first_axis, 'XLim') * scale_factor_xaxis);
set(ax2, 'XScale', get(first_axis, 'XScale')); %// make logarithmic if first axis is too
xlabel('second x label')
The next step should be to put also a second scale and label to the y-axis. But I this won't work with the next part of the code:
ax2 = axes('Position', get(first_axis, 'Position') .* [1 1 1 1e-12] - [0 sqzy 0 0],'Color','r');
ylim(get(first_axis, 'YLim') * scale_factor_yaxis);
set(ax2, 'YScale', get(first_axis, 'YScale')); %// make logarithmic if first axis is too
ylabel('second y label')
With this the second y-label is plotted next to the second x-axis and the second y-scale is a x-scale. But I do not understand the code enough to get this the way I describe.

3D Surface plot misplaced axis

The code is:
subplot(1,3,3)
h=surf(ReflMatrix)
set(h, 'edgecolor','none')
colormap winter %Other colourmaps: Winter,Cool
hold on;
ylabel('frequency (Hz)');
xlabel('angle of incidence (degrees)');
alpha(.5) %transparency
The ReflMatrix is 401x90. The values of y range from 0 to 90, which is good because y is angle measured in degrees . The values of x (frequency) range from 0 to 401 because my bandwidth is 401 frequencies but I would like the same graph with values ranging from 300 to 700 (instead of starting from frequency 0 to start from frequency 300).
In surf you can specify your x and y. In your case, define your frequency by
y = linspace(300,700,401);
and the phase by
x = linspace(0,90,91);
Are you sure with the size of ReflMatrix, since frequencies from 0 to 90 are 91 points rather than 90. Then set your x and y parameters according to
[X,Y] = meshgrid(x,y);
h = surf(X,Y,ReflMatrix);
EDIT:
You can set the limits of the axes accordingly by
xlim([0 90]);
ylim([300 700]);
zlim([min(min(ReflMatrix)) max(max(ReflMatrix))]);

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.

Axes tick labelling after using imagesc in Matlab

I am trying to plot a 512*512 matrix with specified axes values. This is the code I am using but somehow the returned figure still shows the axes labelled as 512 * 512.
x = [0,1];
y = [0,100];
X = reshape(prob_to_1,512,512);
colormap('hot');
figure;
subplot(1,1,1);
axis([0 1 0 100]);
imagesc(X);
I want the final figure to be labelled between 0-1 on y-axes and between 0-100 on the x-axes.
Any suggestions/ideas?
Thanks!!
Unfortunately you cannot do it directly but have to set custom tick labels like this:
X = magic(512); % just some test data
imagesc(X);
set(gca, 'XTick', [0:0.1:1]*512, 'XTickLabel', [0:0.1:1]*100) % 10 ticks
set(gca, 'YTick', [0:0.05:1]*512, 'YTickLabel', [0:0.05:1]) % 20 ticks
Adjust the spacing of the ticks to change the number of ticks accordingly.

Hist3 Plotting and Axes Range

I'm plotting a 3-D histogram with MATLAB and it's working pretty ok, except for the different axes ranges. I'd like them to be defined in a way, where equal value pairs lie on the bisecting line.
My code looks like this (more or less "stolen" from the hist3 MATLAB example):
[vec_voxel_ids, vec_dose_values_reference, vec_dose_values_control] = ...
textread('_BOOSTINT_voxel_data.txt', '%u %u %u');
mat_dose_values = [vec_dose_values_reference, vec_dose_values_control];
hist3(mat_dose_values, [100, 100]);
xlabel('Dose Reference');
ylabel('Dose Control');
set(gcf, 'renderer', 'opengl');
set(get(gca,'child'), 'FaceColor', 'interp', 'CDataMode', 'auto');
This is how it looks:
In order to reposition the bins to align their centers the ticks and also choose the range of the bin values you can use hist3's 'edges' option (similar to that in histc):
data = 500+5*randn(1e3,2); % dummy data
d = 1; % width for x and y bins
x = 480:d:520; % range for x bins
y = x; % use same range for y bins, can be different
hist3(data, 'edges', {x-d/2,y-d/2}); % subtract half bin width to center bins
set(gcf, 'renderer', 'opengl');
set(get(gca,'child'), 'FaceColor', 'interp', 'CDataMode', 'auto');
view(2)
axis equal
axis([478 522 478 522])
grid minor
xlabel('x')
ylabel('y')
This example produces something like this:
Note, that this is a re-binning of your data so your output may look slightly different compared to before. The bins have been shifted to align their centers and the histogram recalculated.