Reconstruct 3D graph with surf in matlab? - matlab

I usually use surf function to plot 3D figures in matlab, but now the data is different, so I am using plot3 and I have the below figure. Do you have any idea how I reconstruct this figure to be more understandable even if by using different function.
To be more concise, I have X values, with each X value there is a value of Y and value of Z.
X = [ 1 ;2 ;4; 8; 16; 32; 64];
Z = [ 1; 1.8 ; 3.46 ; 6.74 ; 13.18 ; 24.34 ; 39.33]
Y = [0 ; 56.92 ; 91 ; 109.95 ; 119 ; 123.57 ; 125.51]
fig = plot3(log(X),Y,Z,'b.-');
XLABEL=[ 1 2 4 8 16 32 64];
set(gca,'XTickLabel',XLABEL);
set(gca,'XTick',log(XLABEL));
YLABEL= [ 0 30 60 90 120 150 180];
set(gca,'YTickLabel',YLABEL);
set(gca,'YTick',YLABEL);
ZLABEL= [0 5 10 15 20 25 30 35 40 45 50 55];
set(gca,'ZTickLabel',ZLABEL);
set(gca,'ZTick',(ZLABEL));
ylim([0 180]);
zlim([0,55]);
grid on

It's difficult to say, because we don't have a context. Common options are:
Plotting x/y and x/z in two separate plots. Precisely readable but difficult to get the connection between y and z. subplot
Plotyy, same as previous but in one plot. Y and Z values which correspond to the same x-value are aligned. plotyy
Use a plot3 as shown above, but connect each point to the x/z plane. (details below)
Project the line on one or multiple planes and draw it there. (Plot the line again, setting x, y or z to 7 0 or 180, which is the location of your axis)
If two axis are of major importance, use a simple 2d plot and represent the third dimension using color/dotsize/annotations etc...
Code for Option 3:
At the end of your code, add the following code:
X2=[X';X';nan(size(X'))];
X2=X2(:);
Y2=[Y';Y';nan(size(Y'))];
Y2=Y2(:);
Z2=[Z';zeros(size(Z'));nan(size(Z'))];
Z2=Z2(:);
hold on
plot3(log(X2),Y2,Z2,'--')
To understand it, you have to know that matlab skips nans while plotting. Thus the code above generates a independent line segment for each point, connecting it to the ground plane.

Related

How to plot an n-points discrete segment between two given points in Matlab?

Given two points, what's the best way to plot - in Matlab - a n-points discrete segment that has these points as extremes?
What if I have to plot a chain of discrete segments like that?
Thank you in advance!
The following is an example of what I'm trying to achieve in the easiest possible way
Assuming your points are stored in the fashion p = [35,0; 40,0.2; 45,0], i.e.
p =
35.0000 0
40.0000 0.2000
45.0000 0
Then you can create an array for all x values by finding the mininum and maximum values of the x coordinate. Here, the x coordinate is the first column of p, i.e. p(:,1). You can use the colon operator : to create the x array by
x = min(p(:,1)) : 1 : max(p(:,1))
The 1 in the middle is the step width. For your example, this will create the array
x =
35 36 37 38 39 40 41 42 43 44 45
Now you can interpolate all y value linearly with the interp1 function. This does a linear interpolation by default. The syntax is thus
y = interp1(p(:,1), p(:,2), x)
Finally you can plot the vectors x and y using plot. If you only want to print circles, use 'o' as LineSpec specifier. To connect the circles using a line, use '-o'. There's an extensive list of options here. You can also add the color of the line / markers to this format spec. Black circles would be 'ok':
plot(x, y, 'ok')

How do I change the number of ticks in matlab histogram and change axis numbers font size

I only want
the x-axis to display 1 2 3 4 5 6
the y-axis to display 0 20 40 60 80 100
change the numbers font size to 14
I've tried by setting different axis property (ref. to the commented lines of code in the script below) however none of them affect the graph.
%Code to generate the diceSum
DiceSum = myDiceRoller(1,500);
figure(1)
%Create the histogram
hist(DiceSum,NDice*6)
%Label the axes
xlabel('Value of Roll','FontSize',16)
ylabel('Number of Times Rolled','FontSize',16)
%set(gca,'X','FontSize',14)
%set(gca,'YTickLabel',{'0' ;'100'})
%set('xtick','FontSize',14)
%set('Xlim',[0,6], 'Ylim',[0 ,100])
%set('xtick',[0:1:6],'ytick',[0:20:100])
%set(gca,'XLim',[0 6])
%set(gca,'XTick',[0 1 2 3 4 5 6])
%set(gca,'XTickLabel',str2mat{'0','1','2','3','4','5','6')
%xlim([0 6])
This is a separate function I'm using to create the data and the histogram
function [DiceSum] = myDiceRoller(NDice,NRolls)
DiceSum = zeros(1,NRolls);%
for i = 1:NRolls;% on roll 1...roll 2
for j = 1:NDice;% on roll 1 , roll #s of die
n = ceil(rand(1)*6);
DiceSum(1,i) = DiceSum(1,i) + n;
end
hist(DiceSum,NDice*6)
xlabel('Value of Roll')
ylabel('Number of Times Rolled')
end
To have the x-axis displaying 1 2 3 4 5 6 you have to two possibilities:
to change the way you call the hist function as follows:
% hist(DiceSum,1:NDice*6)
hist(DiceSum,1:6)
this because in the call to hist with 2 parameters, the second one should be a vector, in that case, hist returns the distribution of Y among length(x) bins with centers specified by x (being x the second parameter) - R2012b hist help
to directly set the x-axis xtick as follows:
set(gca,'xtick',[0:6])
To have the y-axis displaying 0 20 40 60 80 100 you have to set the y-axis ytick as follows:
set(gca,'ytick',[0:20:100])
To change the x and y axis tick font size to 14 you have to set the axis fontsize as follows:
set(gca,'FontSize',14)
Hope this helps.

Unwanted line shows up in matlab 3d triplet line

I am plotting 3d lines using MATLAB's plot3 command.
I have arranged my data into X, Y, Z triplets to run through the function as such:
Where points is an array with 6 columns.
The 1st three columns in row one are the coordinates of the i'th node of the 1st element. Similarly the 2nd three columns are the j'th node's coordinates.
points =
[x1 y1 z1 x2 y2 z2]
0 0 0 60 0 0
60 0 0 90 0 0
60 0 30 60 0 0
60 0 30 60 30 30
60 30 30 60 30 0
plot3 ( [x1 ;x2] , [y1 ; y2] , [z1 ; z2], '-or')
With some other processing my result is this:
Looking closely at the points table, there is no such line that goes from between points [60 0 0] and [60 30 30]
Does anyone have any advice for how I might remove this unsightly artefact?
Note: The analysis using these elements and nodes are not affected, I suspect it is purely graphical.
Yes, you are correct. It is graphical.
The way MATLAB plots points is that it connects a line between successive points. Therefore, it joins a line between points 1 and 2, then 2 and 3, 3 and 4, etc.
If you want to achieve what you want, so without the diagonal line, you'll need to plot the lines in a particular order. What I would do is first plot the line parallel to the z = 0 axis, then draw the square shape after.
%// Draw parallel line
plot3([90 0], [0 0], [0 0], '-or');
%// Draw square shape
x = [60 60 60 60];
y = [0 0 30 30];
z = [0 30 30 0];
hold on;
plot3(x, y, z, '-or');
axis ij; %// Invert y axis
Take a look at how I defined the square shape. I started from the left of the shape, then traced around in a clockwise manner. I first plot the parallel line, then the square shape after.
This is what I get:
I am trying to plot a system of links that are between nodes, connections are made at nodes, both links and nodes are defined explicitly. For example, one must have nodes1 N1 and N2 to create a link L1(N1,N2). I form this information into an array where row1 = [N1 N2] where N contains a 3 column vector with the cartesian coordinate. I have partitioned out the X,Y,Z vectors from this matrix and attempted to pass them all together into the plot3 command. As shown in a simple case, this lead to the plot of another line segment that was unintentional (frankly I am still not clear as to why). The surefire way that I have found is by looping over the X,Y,Z vectors and plotting the segments individually.
hold on
for i = 1:length(x1)
plot3 ( [x1(i) ;x2(i)] , [y1(i) ; y2(i)] ,[z1(i);z2(i)], '-or')
end
hold off

MATLAB Data Interpolation - Basics

I have a dataset consisting of a position and a signal - the signal is sampled at scattered positions (0, 115, 230....):
0 1.709219858
115 1.676595745
230 1.643026005
345 1.609456265
460 1.574940898
575 1.540898345
690 1.506855792
806 1.473286052
I would like to smooth this data and then interpolate it to fill in the intervening positions i.e.:
0 x
1 x
2 x
3 x
4 x
5 x
6 x
7 x
8 x
9 x
10 x
Where x is the smoothed signal. I've been smoothing data with the commands:
>> hann250=hanning(250);
>> smooth250=conv(signal,hann250,'same');
But I am not sure at all how to interpolate the data - what commands can I use and what would I type? I'm totally new to MATLAB! I am also not sure what interpolation method I need but I intend to try various one's and see (once I know how!). Thanks,
T
You could try spline interpolation:
http://www.mathworks.com/help/matlab/ref/spline.html
% read x, y from your file
xx = linspace(min(x), max(x), 1000); % generate 1000 equally spaced points
yy = spline(x,y,xx); % interpolate
plot(x,y); % original
hold all;
plot(xx,yy); % new
You can use interp1:
data = [0 1.7092
115.0000 1.6766
230.0000 1.6430
345.0000 1.6095
460.0000 1.5749
575.0000 1.5409
690.0000 1.5069
806.0000 1.4733];
index_interp = 0:806; %// indices on which to interpolate
data_interp = interp1(data(:,1),data(:,2),index_interp,'linear');
There are other interpolation methods available in addition to 'linear'; see the above link.

How to mark the peak with Matlab?

How can I use the plot function to mark the peak?
Example:
a = [0 1 3 23 3 9 10 28 2]
[p,locs] = findpeaks(a)
Result:
p =
23 28
locs =
4 8
You dont provide an x range so create one (you can change this to what you want).
figure
x = [1:length(a)];
plot(x,a,'k');
The above plots your original data points the following will
hold on
plot(locs,p,'ro');
plot your peaks as red circle points on top of the original series. If you need a non-integer x-range you will need to calculate the appropriate values that correspond to the indices in your locs array and use those x values instead.