Data label on each entry in xy scatter - matlab

I have an x-y scatter plot in MATLAB and want to put a data label on each point. I can't seem to find this in the documentation. Is it possible?

Example:
p = rand(10,2);
scatter(p(:,1), p(:,2), 'filled')
axis([0 1 0 1])
labels = num2str((1:size(p,1))','%d'); %'
text(p(:,1), p(:,2), labels, 'horizontal','left', 'vertical','bottom')

Related

matlab contour plot specific value

I have made a contour plot in matlab (See code). And I want to find the contour line where the value is equal to 1. Now I just have found it approximately between to lines contour plot:
Can this be done? For example if I want to plot 5 contour lines from the values 0 to 1
Update I managed to plot contour line equal to 1, but I want the contour lines inside, not outside the contour line =1 as I get with this code.
[x,y] = meshgrid(-3 : 0.01: 3, -3 : 0.01: 3);
s = x + i*y;
z=abs(1+s+((s.^2)/2)+((s.^3)/6));
figure;
[C,h] = contour(x,y,z,[1 1]);
clabel(C,h)
hold on;
[R,k] = contour(x,y,z,25);
clabel(R,k)
How about:
[C,h] = contour(x,y,z,0.1:0.1:1);
clabel(C,h)
% no need for 'hold on' and all the rest...
That's what you look for?

hist3 plot with additional z axis

The following code creates a 2D stacked histogram for two 2D distributions:
%%first dataset
x1 = 200 + 300.*rand(1000,1)'; %rand values between 0 and 200
y1 = 100 + 250.*rand(1000,1)'; %rand values between 100 and 500
%%secnd dataset
x2 = 100 + 200.*rand(1000,1)'; %rand values between 0 and 200
y2 = 200 + 400.*rand(1000,1)'; %rand values between 100 and 500
one = linspace(100,400,20);
two = linspace(100,500,20);
EDGES = {one, two}; %edges
[n1,c1] = hist3([x1' y1'],'Edges',EDGES);%first dataset
[n2,c2] = hist3([x2' y2'],'Edges',EDGES);%second dataset
figure('Color','w');
% plot the first data set
bh=bar3(n1);
% Loop through each row and shift bars upwards
for ii=1:length(bh)
zz = get(bh(ii),'Zdata');
kk = 1;
% Bars are defined by 6 faces(?), adding values from data2 will
% shift the bars upwards accordingly, I'm sure this could be made
% better!
for jj = 0:6:(6*length(bh)-6)
zz(jj+1:jj+6,:)=zz(jj+1:jj+6,:)+n2(kk,ii);
kk=kk+1;
end
%erase zero height bars
%# get the ZData matrix of the current group
Z = get(bh(ii), 'ZData');
%# row-indices of Z matrix. Columns correspond to each rectangular bar
rowsInd = reshape(1:size(Z,1), 6,[]);
%# find bars with zero height
barsIdx = all([Z(2:6:end,2:3) Z(3:6:end,2:3)]==0, 2);
%# replace their values with NaN for those bars
Z(rowsInd(:,barsIdx),:) = NaN;
%# update the ZData
set(bh(ii), 'ZData',Z)
end
% Set face colour to blue for data1
set(bh,'FaceColor',[0 0 1]);
% Apply hold so that data2 can be plotted
hold on;
% Plot data2
bh=bar3(n2);
%erase zero height bars
for ii=1:numel(bh)
%# get the ZData matrix of the current group
Z = get(bh(ii), 'ZData');
%# row-indices of Z matrix. Columns correspond to each rectangular bar
rowsInd = reshape(1:size(Z,1), 6,[]);
%# find bars with zero height
barsIdx = all([Z(2:6:end,2:3) Z(3:6:end,2:3)]==0, 2);
%# replace their values with NaN for those bars
Z(rowsInd(:,barsIdx),:) = NaN;
%# update the ZData
set(bh(ii), 'ZData',Z)
end
% Set face color to red
set(bh,'FaceColor',[1 0 0]);
%set ticks
set(gca,'XTick',1:6:numel(one),'XTickLabel',one(1:6:end))
set(gca,'YTick',1:6:numel(one),'YTickLabel',one(1:6:end))
view(20,40)
%labels
xlabel('x')
ylabel('y')
zlabel('z')
%set transparency
set(gcf,'renderer','opengl');
set(get(gca,'child'),'FaceAlpha',0.8);
set(get(gca,'child'),'EdgeAlpha',0.3);
A first issue is the transparency (but I think it is a problem of my matlab version 2014a, so I am not bothered by that). It just makes all blurry.
My question is how to add a mesh plot on the same picture. The code creating the meshes is the following:
%create surface I want to plot
[X,Y] = meshgrid(one,two);
inds1=find(X(:).*Y(:)<.3e5);%condition
inds2=find(X(:).*Y(:)>.3e5);
I=Y./X.^2;%first surface
I(inds1)=NaN;%second surface
figure('Color','w');hold on
mesh(X,Y,I,'FaceColor',[0 0 1],'EdgeColor','none')
I(:,:)=NaN;
I(inds1)=Y(inds1)./X(inds1);%second surface
mesh(X,Y,I,'FaceColor',[1 0 0],'EdgeColor','none')
alpha(.5)
grid on
view(20,40)
%labels
xlabel('x')
ylabel('y')
zlabel('z')
The domain of the histograms and the meshes are the same. So I just need to add an extra z-axis on the first figure.
I tried substituting figure('Color','w');hold on in the second code with AxesH = axes('NextPlot', 'add');, but I was really wrong about that:
That just overlayed the two figures..
I also tried something along the lines of:
%add axis
axesPosition = get(gca,'Position'); %# Get the current axes position
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Color','none',... %# ... with no background color
'ZLim',[0 400],... %# ... and a different scale
'ZAxisLocation','right',... %# ... located on the right
'XTick',[],... %# ... with no x tick marks
'YTick',[],... %# ... with no y tick marks
'Box','off');
but it is not feasible because the property ZAxisLocation does not exist.
Does anyone know how to add the z-axis?
Also, if you have other comments on how to ameliorate the code, they're welcome!
acknowledgements
2d stacked histogram:https://stackoverflow.com/a/17477348/3751931
erasing the zero values in the hist plot: https://stackoverflow.com/a/17477348/3751931
I now think that this is not yet possible (http://www.mathworks.com/matlabcentral/answers/95949-is-there-a-function-to-include-two-3-d-plots-with-different-z-axes-on-the-same-plot-area-similar-to).
So I just added a fake axis:
[X,Y] = meshgrid(one,two);
inds1=find(X(:).*Y(:)<.3e5);%condition
inds2=find(X(:).*Y(:)>.3e5);
s=Y./X.^2;%first surface
s(inds1)=NaN;%second surface
%mesh(X,Y,I,'FaceColor',[0 0 1],'EdgeColor','none')
mesh((X-min(min(X)))/max(max(X-min(min(X))))*20,(Y-min(min(Y)))/max(max(Y-min(min(Y))))*20,...
s/max(max(s))*max(max(n1))+max(max(n1)),'FaceColor','g','EdgeColor','none','facealpha',.5)
s(:,:)=NaN;
s(inds1)=Y(inds1)./X(inds1);%second surface
%mesh(X,Y,I,'FaceColor',[1 0 0],'EdgeColor','none')
mesh((X-min(min(X)))/max(max(X-min(min(X))))*20,(Y-min(min(Y)))/max(max(Y-min(min(Y))))*20,...
s/max(max(s))*max(max(n1))+max(max(n1)),'FaceColor','y','EdgeColor','none','facealpha',.5)
alpha(.5)
grid on
%add fake z axis
line([20 20],[1 1],[max(max(n1))-min(min(s)) 20],...
'color','g','linewidth',2)
% text(20*ones(1,5),zeros(1,5),linspace(max(max(n1))-min(min(I)),20,5),...
% num2str(linspace(0,max(max(I)),5)),'color','g')
z=linspace(max(max(n1))-min(min(s)),20,5);
txto=linspace(0,max(max(s)),5);
for ii=1:5
line([20 20.3],[1 1],[z(ii) z(ii)],'color','g')%ticks
text(20,0,z(ii),num2str(txto(ii)),'color','g')%ticklabel
end
text(19.8,1,21,'s','color','g')%label
Over all the code is quite ugly and needs a lot of tuning..

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.

Plot outside axis in Matlab

How to plot something outside the axis with MATLAB? I had like to plot something similar to this figure;
Thank you.
Here is one possible trick by using two axes:
%# plot data as usual
x = randn(1000,1);
[count bin] = hist(x,50);
figure, bar(bin,count,'hist')
hAx1 = gca;
%# create a second axis as copy of first (without its content),
%# reduce its size, and set limits accordingly
hAx2 = copyobj(hAx1,gcf);
set(hAx2, 'Position',get(hAx1,'Position').*[1 1 1 0.9], ...
'XLimMode','manual', 'YLimMode','manual', ...
'YLim',get(hAx1,'YLim').*[1 0.9])
delete(get(hAx2,'Children'))
%# hide first axis, and adjust Z-order
axis(hAx1,'off')
uistack(hAx1,'top')
%# add title and labels
title(hAx2,'Title')
xlabel(hAx2, 'Frequency'), ylabel(hAx2, 'Mag')
and here is the plot before and after:
You can display one axis with the scale you want, then plot your data on another axis which is invisible and large enough to hold the data you need:
f = figure;
% some fake data
x = 0:20;
y = 23-x;
a_max = 20;
b_max = 23;
a_height = .7;
%% axes you'll see
a = axes('Position', [.1 .1 .8 a_height]);
xlim([0 20]);
ylim([0 20]);
%% axes you'll use
scale = b_max/a_max;
a2 = axes('Position', [.1 .1 .8 scale*a_height]);
p = plot(x, y);
xlim([0 20]);
ylim([0 b_max]);
set(a2, 'Color', 'none', 'Visible', 'off');
I had similar problem and I've solved it thanks to this answer. In case of bar series the code is as follows:
[a,b] = hist(randn(1000,1)); % generate random data and histogram
h = bar(b,a); % plot bar series
ylim([0 70]) % set limits
set(get(h,'children'),'clipping','off')% turn off clippings

Matlab question: fixing the scale of Y axis in hist

I want to draw several histograms. But I want the Y axis to be fixed, like from 1000 to 1 by 100. How can I specify them。
Please advise.
Consider this example:
%# some data
X = randn(1000,3);
nbins = 10;
%# compute frequencies and bins
%#[count,bins] = hist(X, nbins);
count = zeros(10,size(X,2));
bins = zeros(10,size(X,2));
for i=1:size(X,2)
[count(:,i),bins(:,i)] = hist(X(:,i),nbins);
end
%# show histograms
for i=1:size(X,2)
subplot(1,size(X,2),i)
bar(bins(:,i), count(:,i),'hist')
set(gca, 'YTick',0:100:4000, 'YLim',[0 400])
end
The axis command is what you're looking for. You specify the [XMIN XMAX YMIN YMAX]. This example will have all histograms capped at a value of 5. Also, you're asking a bunch of questions about MATLAB today without seemingly doing any research. Please ask a search engine and show that you've at least tried something.
clf;
subplot(1,2,1); hist(rand(1,10)); axis([0 1 0 5]);
subplot(1,2,2); hist(rand(1,10)); axis([0 1 0 5]);