pcolor in scatter plot matlab - matlab

I have a large matrix DAT(50000+,42). I am plotting 2 rows of this matrix on the x and y axes, and want the plot points to vary in color due to the value of a separate row. Can anybody advise? pcolor will not work for me due to "color data input must be a matrix" error.
TIA
X = DAT(:,21);
Y = DAT(:,22);
Z = DAT(:,28);
plot(X,Y,'*');
hold on
pcolor(X,Y,Z);
hold off

You could consider using scatter()
% random sample data
DAT = randn(30,42);
X = DAT(:,21);
Y = DAT(:,22);
Z = DAT(:,28);
scatter(X,Y,50,Z); % x,y,size,color -> size can also be a vector
% scatter(X,Y,50,Z,'*'); % to also change the marker type

You can select the colors from an array generated with colormap like this:
DAT = randn(30,42);
X = DAT(:,21);
Y = DAT(:,22);
Z = DAT(:,28);
[dummy ID]=sort(Z);
colors=colormap(jet(length(Z)));
figure
for i=1:length(Z)
plot(X(i),Y(i),'*','Color',colors(ID(i),:));
hold on
end
The only issue with this technique is that you cannot do plots with millions of points because of the looped plotting, but otherwise it works like a charm:

Related

How can I plot only a specific range of a curve, while having axis with higher limits?

I need to plot a section of curve, using MATLAB. But I need my axes to be larger than the part I am showing.
For example, I have the following data:
x = 0:50
y = 0.5*x
I would like to plot this data from x=0 to x=20, with xlim([0 50]).
Just to clarify, I do not want to change the range of values of x, I just want to change what is shown on the graph.
Say you have some data
x = 0:50;
y = 0.5*x;
and you would like to plot only a part of it, say everything where x<=20. You can do as follows:
index = x <= 20;
plot(x(index), y(index))
xlim(x([1,end])) % set the x-axis limit to the range of all your `x` values
ylim([min(y),max(y)]) % set the y-axis limit to the range of all your `y` values
Do this:
x = 0:20
y = 0.5*x
plot(x,y)
xlim([0 50]) % This will set x-axis to the desired range
ylim([min(y) max(y)])

Matlab plot: equal distance between ticks

I have this 3D plot that I'm making but the data are not linear. This implies that on my plot, the distance between the ticks that I want to show is not equal. How can I adapt the scale of the x and y axis so that this is the case, i.e. so that the axis gets divided into equal parts with the current ticks?
I want the same ticks and tick labels, but that they just have an equal distance in between them on the axes, in stead of small between 0.1 and 0.5 and large between 1 and 5.
The current plot looks like this:
RMSEval = xlsread('RMSEvalues.xlsx');
X = RMSEval(:,1);
Y = RMSEval(:,2);
Z = RMSEval(:,3);
figure(1);
xi = linspace(min(X),max(X),30);
yi= linspace(min(Y),max(Y),30);
[XI,YI] = meshgrid(xi,yi);
ZI = griddata(X,Y,Z,XI,YI);
contourf(XI,YI,ZI);
colormap('jet');
xticks([1e-13 5e-13 1e-12 5e-12 1e-11]);
yticks([1e-18 5e-18 1e-17 5e-17 1e-16]);
colorbar;
A plot where the distance between 0.1 and 0.5 is the same as between 1 and 5 would be a log plot, specifically a log-log plot since you want it on both axes. One way to achieve this would be to transform the X and Y values of your data logarithmically and modify the tick mark labels to match the untransformed values rather than the logarithmic ones you're actually plotting.
A rough guess at a solution is below. I say a rough guess because without posting the data you're importing from the xlsx file or a paired down version of that data (as in an MWE) I can't actually test it.
RMSEval = xlsread('RMSEvalues.xlsx');
X = log(RMSEval(:,1));
Y = log(RMSEval(:,2));
Z = RMSEval(:,3);
figure(1);
xi = linspace(min(X),max(X),30);
yi= linspace(min(Y),max(Y),30);
[XI,YI] = meshgrid(xi,yi);
ZI = griddata(X,Y,Z,XI,YI);
contourf(XI,YI,ZI);
colormap('jet');
xticks(log([1e-13 5e-13 1e-12 5e-12 1e-11]));
xticklabels(cellfun(#num2str,num2cell(),'UniformOutput',false));
yticks(log([1e-18 5e-18 1e-17 5e-17 1e-16]));
yticklabels(cellfun(#num2str,num2cell([1e-18 5e-18 1e-17 5e-17 1e-16]),'UniformOutput',false));
colorbar;

In Matlab, how to draw lines from the curve to specific xaxis position?

I have a spectral data (1000 variables on xaxis, and peak intensities as y) and a list of peaks of interest at various specific x locations (a matrix called Peak) which I obtained from a function I made. Here, I would like to draw a line from the maximum value of each peaks to the xaxis - or, eventually, place a vertical arrow above each peaks but I read it is quite troublesome, so just a vertical line is welcome. However, using the following code, I get "Error using line Value must be a vector of numeric type". Any thoughts?
X = spectra;
[Peak,intensity]=PeakDetection(X);
nrow = length(Peak);
Peak2=Peak; % to put inside the real xaxis value
plot(xaxis,X);
hold on
for i = 1 : nbrow
Peak2(:,i) = round(xaxis(:,i)); % to get the real xaxis value and round it
xline = Peak2(:,i);
line('XData',xline,'YData',X,'Color','red','LineWidth',2);
end
hold off
Simple annotation:
Here is a simple way to annotate the peaks:
plot(x,y,x_peak,y_peak+0.1,'v','MarkerFaceColor','r');
where x and y is your data, and x_peak and y_peak is the coordinates of the peaks you want to annotate. The add of 0.1 is just for a better placing of the annotation and should be calibrated for your data.
For example (with some arbitrary data):
x = 1:1000;
y = sin(0.01*x).*cos(0.05*x);
[y_peak,x_peak] = PeakDetection(y); % this is just a sketch based on your code...
plot(x,y,x_peak,y_peak+0.1,'v','MarkerFaceColor','r');
the result:
Line annotation:
This is just a little bit more complicated because we need 4 values for each line. Again, assuming x_peak and y_peak as before:
plot(x,y);
hold on
ax = gca;
ymin = ax.YLim(1);
plot([x_peak;x_peak],[ymin*ones(1,numel(y_peak));y_peak],'r')
% you could write instead:
% line([x_peak;x_peak],[ymin*ones(1,numel(y_peak));y_peak],'Color','r')
% but I prefer the PLOT function.
hold off
and the result:
Arrow annotation:
If you really want those arrows, then you need to first convert the peak location to the normalized figure units. Here how to do that:
plot(x,y);
ylim([-1.5 1.5]) % only for a better look of the arrows
peaks = [x_peak.' y_peak.'];
ax = gca;
% This prat converts the axis unites to the figure normalized unites
% AX is a handle to the figure
% PEAKS is a n-by-2 matrix, where the first column is the x values and the
% second is the y values
pos = ax.Position;
% NORMPEAKS is a matrix in the same size of PEAKS, but with all the values
% converted to normalized units
normpx = pos(3)*((peaks(:,1)-ax.XLim(1))./range(ax.XLim))+ pos(1);
normpy = pos(4)*((peaks(:,2)-ax.YLim(1))./range(ax.YLim))+ pos(2);
normpeaks = [normpx normpy];
for k = 1:size(normpeaks,1)
annotation('arrow',[normpeaks(k,1) normpeaks(k,1)],...
[normpeaks(k,2)+0.1 normpeaks(k,2)],...
'Color','red','LineWidth',2)
end
and the result:

Gradual color for points in matlab 3d scatter according to number in the list

I have data that includes coordinates x,y,z. I made a 3d scatter plot. However, it's essential for me to see the sequence of these points according to the index number by filling the points with gradual color.
My current code is
data = importdata('12.txt');
x = data (:,1);
y = data (:,2);
z = data (:,3);
scatter3 (x,y,z);
xlabel ('S1');
ylabel ('S2');
zlabel ('S3');
title ('3d scatter plot for 2nd specimen');
scatter3(x,y,z,'filled')
view(-30,10)
P.S. Matlab is new for me.
I give you an example:
x = 1:10;
y = 1:10;
z = 1:10;
MarkerSize = 5;
SizeVector = repmat(MarkerSize ,length(x),1);
ColorVector = summer(length(x));
h = scatter3(x,y,z,SizeVector,ColorVector,'filled');
view(-30,10)
Matlab can generate color vectors (RGB) for different colormap.
In this case I choose the summer's colormap, but if you check the doc there is a lot of different options.
Result:

Matlab - Trying to use vectors with grid coordinates and value at each point for a color plot

I'm trying to make a color plot in matlab using output data from another program. What I have are 3 vectors indicating the x-position, y-yposition (both in milliarcseconds, since this represents an image of the surroundings of a black hole), and value (which will be assigned a color) of every point in the desired image. I apparently can't use pcolor, because the values which indicate the color of each "pixel" are not in a matrix, and I don't know a way other than meshgrid to create a matrix out of the vectors, which didn't work due to the size of the vectors.
Thanks in advance for any help, I may not be able to reply immediately.
If we make no assumptions about the arrangement of the x,y coordinates (i.e. non-monotonic) and the sparsity of the data samples, the best way to get a nice image out of your vectors is to use TriScatteredInterp. Here is an example:
% samplesToGrid.m
function [vi,xi,yi] = samplesToGrid(x,y,v)
F = TriScatteredInterp(x,y,v);
[yi,xi] = ndgrid(min(y(:)):max(y(:)), min(x(:)):max(x(:)));
vi = F(xi,yi);
Here's an example of taking 500 "pixel" samples on a 100x100 grid and building a full image:
% exampleSparsePeakSamples.m
x = randi(100,[500 1]); y = randi(100,[500 1]);
v = exp(-(x-50).^2/50) .* exp(-(y-50).^2/50) + 1e-2*randn(size(x));
vi = samplesToGrid(x,y,v);
imagesc(vi); axis image
Gordon's answer will work if the coordinates are integer-valued, but the image will be spare.
You can assign your values to a matrix based on the x and y coordinates and then use imagesc (or a similar function).
% Assuming the X and Y coords start at 1
max_x = max(Xcoords);
max_y = max(Ycoords);
data = nan(max_y, max_x); % Note the order of y and x
indexes = sub2ind(size(data), max_y, max_x);
data(indexes) = Values;
imagesc(data); % note that NaN values will be colored with the minimum colormap value