Plot 3D points in Matlab - matlab

I want to plot 3D points in Matlab in different colors depending on a value. I've got following code, but this does not work because plot3d needs a vector.
x = vdhf_data.data(:,1);
y = vdhf_data.data(:,2);
z = vdhf_data.data(:,3);
data = vdhf_data.data(:,4);
grid on
hold all
for k=1:length(x)
if data(k) < 6
plot3d(x(k), y(k), z(k), 'ws--', 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'r')
else
plot3d(x(k), y(k), z(k), 'ws--', 'MarkerEdgeColor', 'g', 'MarkerFaceColor', 'g')
end
end
How to do that in Matlab?

I would use
scatter3(x,y,z,ones(size(x)),data,'filled')
This will plot all the points at the same size and color them according to the value of data, using the current colormap. You can also use data to scale the size of each point.
scatter3(x,y,z,data.^-2,data,'filled')

Related

Figure created from contour changes to be in raster format when the number of rows and columns larger than some threshold

A 2D data matrix (data, 100 rows by 100 cols) was plotted using 'contour' function in matlab, and the figure was saved as *.emf file. Expectedly when I insert the emf figure into MS word file, the figure is a vector graphic. But when I improve the resolution of the data, i.e. using imresize in matlab to scale the data matrix with factor 2, and did the same thing as before (plot, save as emf and insert it into word), the figure change to raster format. Is there any settings in matlab that can improve the threshold that keeps vector graphics? The code used is as follows:
path = 'C:\Users\Administrator\Desktop\';
data = importdata([path, 'lsa2.txt'], ' ', 6);
cdata = data.data;
% scale = 2;
% cdata = imresize(cdata, scale);
n = 25;
contourf(cdata,n, 'LineStyle', 'none');
colormap(jet);
axis equal;
First of all don't use imresize if you want a vector image. Imresize is by default raster based and can act weird. Also be more specific with what you want please. If you already have a vector file you can just change it to any size.
Also if you have only a limited data set, you can never really get a true higher resolution, you can only interpolate inbetween points. So use interp2 to resize your data matrix.
[sx,sy] = size(cdata);
fact=1/4; %factor to interpolate over so 4 points per 1
[X,Y]=meshgrid(1:sx); %you can only use this because cdate is square, same size for sx and sy
[xq,yq]=meshgrid(1:fact:sx); %create a new mesh with more points
Cnew=interp2(X,Y,cdata,xq,yq,'spline'); %I suggest spline, probably does what you want
This is the entire code to generate the plot, make sure to save it as an .emf, .svg or .eps if you want a vector image
data = importdata('lsa2.txt', ' ', 6);
cdata = data.data;
rws=3
cls=2;
xl=[22 33]; yl=[13 23];
n = 25;
subplot(rws,cls,1)
contourf(cdata,n, 'LineStyle', 'none');
title('Subplot 1: Original no scaling')
colormap(jet);
axis equal;
xlim(xl);
ylim(yl);
scale = 4;
cresi = imresize(cdata, scale);
subplot(rws,cls,2)
contourf(cresi,n, 'LineStyle', 'none');
title('Subplot 2: Imresize function, scale 4')
colormap(jet);
axis equal;
xlim(scale*xl);
ylim(scale*yl);
[sx,sy] = size(cdata);
fact=1/4; %factor to interpolate over so 4 points per 1
[X,Y]=meshgrid(1:sx); %you can only use this because cdate is square, same size for sx and sy
[xq,yq]=meshgrid(1:fact:sx); %create a new mesh with more points
Cnew=interp2(X,Y,cdata,xq,yq);
subplot(rws,cls,3)
contourf(Cnew,n, 'LineStyle', 'none');
title('Subplot 3: Interp2 "linear", scale 4')
colormap(jet);
axis equal;
xlim(xl/fact);
ylim(yl/fact);
[sx,sy] = size(cdata);
fact=1/4; %factor to interpolate over so 4 points per 1
[X,Y]=meshgrid(1:sx);
[xq,yq]=meshgrid(1:fact:sx);
Cnew=interp2(X,Y,cdata,xq,yq,'spline');
subplot(rws,cls,4)
contourf(Cnew,n, 'LineStyle', 'none');
title('Subplot 4: Interp2 "spline", scale 4')
colormap(jet);
axis equal;
xlim(xl/fact);
ylim(yl/fact);
Cnew=interp2(X,Y,cdata,xq,yq,'cubic');
subplot(rws,cls,5)
contourf(Cnew,n, 'LineStyle', 'none');
title('Subplot 5: Interp2 "cubic", scale 4')
colormap(jet);
axis equal;
xlim(xl/fact);
ylim(yl/fact);
Cnew=interp2(X,Y,cdata,xq,yq,'nearest');
subplot(rws,cls,6)
contourf(Cnew,n, 'LineStyle', 'none');
title('Subplot 6: Interp2 "nearest", scale 4')
colormap(jet);
axis equal;
xlim(xl/fact);
ylim(yl/fact);

MATLAB Color Map defined by segment values

I have a plot in MATLAB that I would like to transform into a colormap (plot shown below). There are several line segments in this plot, and I want each line segment to be colored based on a specific value that is associated with the segment.
For example:
Value of line 1 = 800, plot a specific color
Value of line 2 = 555, plot a specific color
...etc.
Does anyone know how to do this? I have included the part of the code in my program that is making the plots below. In the code I want the color of the line to be dependent on ElementMap(i,6). I don't have a particular preference on the colors as long as I can tell which line segments have a higher value.
Thanks
%% Plot
for i = 1:length(ElementMap)
if ElementMap(i,6) < 1000
x = [ElementMap(i,1);ElementMap(i,3)];
y = [ElementMap(i,2);ElementMap(i,4)];
plot(x,y,['-','b','o']);
hold on;
end
end
You could determine an indexed color for each unique value in the 6th column and then convert these indexed colors to RGB colors using a colormap of your choosing (here we use parula). Then when plotting each line, specify the Color property.
% Get indices to use for the colormap
[~, ~, ind] = unique(ElementMap(:,6));
% Create a colormap of the correct size
cmap = parula(max(ind));
% Create a color for each plot
colors = ind2rgb(ind, cmap);
% Now plot everything
for k = 1:size(ElementMap, 1)
x = [ElementMap(k,1);ElementMap(k,3)];
y = [ElementMap(k,2);ElementMap(k,4)];
plot(x,y, 'Marker', 'o', 'LineStyle', '-', 'Color', colors(k,:));
hold on
end
With this approach, the colors won't necessary scale linearly with your data, but each unique value in ElementMap(:,6) will be represented by a different color and smaller values will be differentiated from larger values.
If you don't care about every plot having a unique value, you could do something like the following which would get you a linear mapping between your colors and values.
values = ElementMap(:,6);
% Assign an index to each
ind = gray2ind(mat2gray(values))
% Create the colormap
cmap = parula(numel(unique(inds)));
% Create a color for each plot
colors = ind2rgb(ind, cmap);
% Now plot everything
for k = 1:size(ElementMap, 1)
x = [ElementMap(k,1);ElementMap(k,3)];
y = [ElementMap(k,2);ElementMap(k,4)];
plot(x,y, 'Marker', 'o', 'LineStyle', '-', 'Color', colors(k,:));
hold on
end
% Now create a colorbar
colorbar()
% Set the range of the colorbar
set(gca, 'CLim', [min(values), max(values)])

Matlab scatter plot of z=f(x,y) with values of z on top of the points

I have a Matlab data set from an equation z=f(x,y).
So for each set of (x,y) I have a corresponding value of z. Can I plot the data on a x,y plane where at each location the z-value is printed instead of a dot or a colored dot?
figure;
hold on;
scatter(x,y);
ma = cellstr(num2str(z(:)));
text(x, y + <some_offset>, ma, 'FontSize', 10, 'Color', 'r');

Shift the z -value of contour plot in Matlab 2014b

I'm trying to make a figure of a surface plot, and beneath the surface I wish to show the contour lines, but I want the contour to be at z = -1 instead of at the default value 0. I found a previous post about this problem here, but when I try the solution the contour is still at z = 0. Maybe it has something to do with the version of MATLAB I'm using, which is 2014b?
Any ideas on how to make it work?
The code I tried:
%# plot surface and contour
Z = peaks;
surf(Z), hold on
[~,h] = contourf(Z); %# get handle to contourgroup object
%# change the ZData property of the inner patches
hh = get(h,'Children'); %# get handles to patch objects
for i=1:numel(hh)
zdata = ones(size( get(hh(i),'XData') ));
set(hh(i), 'ZData',-10*zdata)
end
So, I couldn't really figure out to do it as proposed in the example I found and posted, but I found a way that works. What I ended up doing was basically this:
figure
hold on
surf(X,Y,Z+1);
contour(X,Y,Z);
zz = get(gca,'ZTick');
set(gca,'ZTickLabel',sprintf('%3.1f\n',zz-1));
This gets me the surf and contour in the same figure, but yields some problems with color mappings.
I figured out how to solve the problem with color mappings the user Kine faced. Note: I've done the following code on MATLAB R2015b:
offset = 0.5;
plotHandle = surfc(X1, Y1, Z1);
hold on;
% This line moves the surface up from its original location and increases the space between the surface and the contour plot
plotHandle(1).ZData = plotHandle.ZData + offset;
% However in doing so the color mappings are changed. So, the line below restores these mappings
plotHandle(1).CData = plotHandle.CData - offset;
% This line changes fills the contour plot
plotHandle(2).Fill = 'on';
grid on;
% The following lines draw critical areas on the contour line, as it was more readable in my case
axisHandle = gca;
ZHeight = axisHandle.ZLim(1);
plot3(X2, Y2, ZHeight, 'o', 'MarkerSize', 10, 'LineWidth', 1, 'Color', 'k', 'MarkerFaceColor', 'm');
plot3(Y2, X2, ZHeight, 'o', 'MarkerSize', 10, 'LineWidth', 1, 'Color', 'k', 'MarkerFaceColor', 'm');
hold off
I got the same problem.
And finally, I got the contourf on plane Z=-10.
My MATLAB version is
MATLAB Version: 8.5.0.197613 (R2015a)
hope the codes work 4 you
clear all
clc
[X,Y,Z] = peaks;
[~,hContour] = contourf(X,Y,Z,20,'edgecolor','none');
hContour.ContourZLevel = -10; % set the contour's Z position
view(44,30)
colormap(jet)

Matlab: Adding third dimenstion to 2D plot

I have the following code to generate me a 2D plot or 2 normal distributions:
res = zeros(2, 320);
index = 1:320;
% assign some data to the res array and then approximate:
PD = fitdist(index','normal', 'frequency', res(1,:)')
pdfNormal = normpdf(index',PD.mu,PD.sigma);
plot(index', pdfNormal, 'Color', 'r', 'LineWidth', 2);
hold on;
PD = fitdist(index','normal', 'frequency', res(2,:)')
pdfNormal = normpdf(index',PD.mu,PD.sigma);
plot(index', pdfNormal, 'Color', 'b', 'LineWidth', 2);
This code generates me then the following picture:
Now I am wondering how I could add a third dimension to this plot? Essentially,
I would like to plot another 2 normal distributions, but this time in the Z-axis,
ie., in the third dimension.
Anyone an idea how I could do that easily?
Thanks so much!
If I understood correctly, you can simply give the plots different z-values. Example:
%# some random data
x = 1:300;
y = zeros(5,300);
for i=1:5
y(i,:) = normpdf(x,100+i*20,10);
end
%# plot
hold on
clr = lines(5);
h = zeros(5,1);
for i=1:5
h(i) = plot(x, y(i,:), 'Color',clr(i,:), 'LineWidth',2);
set(h(i), 'ZData',ones(size(x))*i)
end
zlim([0 6]), box on, grid on
view(3)
hold off