I have an n-dimensional matrix, funtointerpolate, and I wish to perform one dimensional interpolation along one of its axes (let's call it axis m). In Python, interpolate functions such as interp1d allow one to specify the axis of interpolation. In MATLAB, I cannot see an obvious way to do this using interp1 or any other built-in interpolate functions. Ideally, the function would look something like
interpolatedfun = interp1(funtointerpolate,oldpoints,newpoints,axis = m)
An obvious way to get around this is to loop over all the other axes in funtointerpolate, but this is rather cumbersome. The motivation for interpolation is that the data in funtointerpolate is evaluated along a non-uniform grid along the m axis. I need it to be uniform along m. Mathematically, suppose I have some tensorial object
A_{ijk}
which is evaluated along a non-uniform grid along the j index. Then, I wish to find a new A such that the jth index consists of values evaluated on a uniform grid. I know the new uniform grid for the jth index, newpoints, and the old grid oldpoints.
You can use the interpn function for this purpose:
newV = interpn(oldAx1, ..., oldAxM, ..., oldAxN, oldV, ...
oldAx1, ..., newAxM, ..., oldAxN);
where V is your output.
(Of course the above is pseudo-code, but it should nicely illustrate the way to solve your problem.)
Related
I am trying trying to graph the polynomial fit of a 2D dataset in Matlab.
This is what I tried:
rawTable = readtable('Test_data.xlsx','Sheet','Sheet1');
x = rawTable.A;
y = rawTable.B;
figure(1)
scatter(x,y)
c = polyfit(x,y,2);
y_fitted = polyval(c,x);
hold on
plot(x,y_fitted,'r','LineWidth',2)
rawTable.A and rawTable.A are randomly generated numbers. (i.e. the x dataset cannot be represented in the following form : x=0:0.1:100)
The result:
second-order polynomial
But the result I expect looks like this (generated in Excel):
enter image description here
How can I graph the second-order polynomial fit in MATLAB?
I sense some confusion regarding what the output of each of those Matlab function mean. So I'll clarify. And I think we need some details as well. So expect some verbosity. A quick answer, however, is available at the end.
c = polyfit(x,y,2) gives the coefficient vectors of the polynomial fit. You can get the fit information such as error estimate following the documentation.
Name this polynomial as P. P in Matlab is actually the function P=#(x)c(1)*x.^2+c(2)*x+c(3).
Suppose you have a single point X, then polyval(c,X) outputs the value of P(X). And if x is a vector, polyval(c,x) is a vector corresponding to [P(x(1)), P(x(2)),...].
Now that does not represent what the fit is. Just as a quick hack to see something visually, you can try plot(sort(x),polyval(c,sort(x)),'r','LineWidth',2), ie. you can first sort your data and try plotting on those x-values.
However, it is only a hack because a) your data set may be so irregularly spaced that the spline doesn't represent function or b) evaluating on the whole of your data set is unnecessary and inefficient.
The robust and 'standard' way to plot a 2D function of known analytical form in Matlab is as follows:
Define some evenly-spaced x-values over the interval you want to plot the function. For example, x=1:0.1:10. For example, x=linspace(0,1,100).
Evaluate the function on these x-values
Put the above two components into plot(). plot() can either plot the function as sampled points, or connect the points with automatic spline, which is the default.
(For step 1, quadrature is ambiguous but specific enough of a term to describe this process if you wish to communicate with a single word.)
So, instead of using the x in your original data set, you should do something like:
t=linspace(min(x),max(x),100);
plot(t,polyval(c,t),'r','LineWidth',2)
I have a 100 x 100 matrix and i have to use plot3 in MATLAB environment to graph this data. I tried plot3(matrix name) but I faced this error "not enough input arguments". I think plot3 needs 3 input arguments, but I only have this matrix of data. could anyone help me to solve this problem? Is there any alternative for plot3 when we don't have enough arguments?
I need a graph like this:
I think you want to plot the values in a figure as a sort of surface element. What you can do then is:
[X,Y] = size(matrix);
figure;
surface(1:X,1:Y,matrix);
What this does is that it creates a vector for both X and Y indices, as possible in surface. The X and Y indices are obtained by setting them as integers from 1:size, so basically you assign the location of each matrix element to an index.
Note that you can strictly speaking use surface(matrix) as well, but the former approach allows you to use custom indexing, as long as the lengths of the vectors X and Y are the same as the size of your matrix.
For the waterfall use:
figure;
waterfall(matrix);
Sample code:
A=rand(100);
figure;
waterfall(1:100,1:100,A);
Gives:
where you can play around with the name-value pairs, see the documentation on that.
I think what you need is mesh or surf instead of plot3.
plot3 draws a line in 3d-space, so it will need three vectors of the same length (one for each dimension).
When you have a matrix, one reasonable way of displaying it is as a surface in 3d space, which is done by the functions mesh and surf.
Try it out! I hope i helps!
I would like to plot some figures like this one:
-axis being real and imag part of some complex valued vector(usually either pure real or imag)
-have some 3D visualization like in the given case
First, define your complex function as a function of (Re(x), Im(x)). In complex analysis, you can decompose any complex function into its real parts and imaginary parts. In other words:
F(x) = Re(x) + i*Im(x)
In the case of a two-dimensional grid, you can obviously extend to defining the function in terms of (x,y). In other words:
F(x,y) = Re(x,y) + i*Im(x,y)
In your case, I'm assuming you'd want the 2D approach. As such, let's use I and J to represent the real parts and imaginary parts separately. Also, let's start off with a simple example, like cos(x) + i*sin(y) which is based on the very popular Euler exponential function. It isn't exact, but I modified it slightly as the plot looks nice.
Here are the steps you would do in MATLAB:
Define your function in terms of I and J
Make a set of points in both domains - something like meshgrid will work
Use a 3D visualization plot - You can plot the individual points, or plot it on a surface (like surf, or mesh).
NB: Because this is a complex valued function, let's plot the magnitude of the output. You were pretty ambiguous with your details, so let's assume we are plotting the magnitude.
Let's do this in code line by line:
% // Step #1
F = #(I,J) cos(I) + i*sin(J);
% // Step #2
[I,J] = meshgrid(-4:0.01:4, -4:0.01:4);
% // Step #3
K = F(I,J);
% // Let's make it look nice!
mesh(I,J,abs(K));
xlabel('Real');
ylabel('Imaginary');
zlabel('Magnitude');
colorbar;
This is the resultant plot that you get:
Let's step through this code slowly. Step #1 is an anonymous function that is defined in terms of I and J. Step #2 defines I and J as matrices where each location in I and J gives you the real and imaginary co-ordinates at their matching spatial locations to be evaluated in the complex function. I have defined both of the domains to be between [-4,4]. The first parameter spans the real axis while the second parameter spans the imaginary axis. Obviously change the limits as you see fit. Make sure the step size is small enough so that the plot is smooth. Step #3 will take each complex value and evaluate what the resultant is. After, you create a 3D mesh plot that will plot the real and imaginary axis in the first two dimensions and the magnitude of the complex number in the third dimension. abs() takes the absolute value in MATLAB. If the contents within the matrix are real, then it simply returns the positive of the number. If the contents within the matrix are complex, then it returns the magnitude / length of the complex value.
I have labeled the axes as well as placed a colorbar on the side to visualize the heights of the surface plot as colours. It also gives you an idea of how high and how long the values are in a more pleasing and visual way.
As a gentle push in your direction, let's take a slice out of this complex function. Let's make the real component equal to 0, while the imaginary components span between [-4,4]. Instead of using mesh or surf, you can use plot3 to plot your points. As such, try something like this:
F = #(I,J) cos(I) + i*sin(J);
J = -4:0.01:4;
I = zeros(1,length(J));
K = F(I,J);
plot3(I, J, abs(K));
xlabel('Real');
ylabel('Imaginary');
zlabel('Magnitude');
grid;
plot3 does not provide a grid by default, which is why the grid command is there. This is what I get:
As expected, if the function is purely imaginary, there should only be a sinusoidal contribution (i*sin(y)).
You can play around with this and add more traces if you need to.
Hope this helps!
I need to make a 3D surface where colour will represent the fourth variable. I know "surf" is SIMILAR to what I need, but that's not quite it. Basically, I have the following variables:
t = [1:m]
y = [1:n]
a = [1:o]
These should be the three Cartesian corodinate axes.
I also have a variable S that is of dimensions m x n x o, and is basically the amplitude, a function of the previous three variables (i.e. S = f(t,y,a)). I want this to be represented by colour.
So to summarize, I need a graph of the form (t,y,a,S), where the first three variables are vectors of unequal sizes and the final variable is a multidimensional array whose dimensions are determined by the first three.
Thanks in advance.
SCATTER3 requires x, y and z and other grouping arguments to be equally-sized Nx1 vectors for a single series or NxM matrices for M series.
You have full space 3D data. To make equally-sized coordinate vectors use MESHGRID (or NDGRID) function:
[X, Y, Z] = meshgrid(t, y, a);
Then you can use SCATTER3:
scatter3( X(:), Y(:), Z(:), [], S(:) )
The problem is since it's full space data scatter3 will not be helpful specially if you have a lot of points.
You can probably filter your S variable (something like idx = S > 0), then you can plot filtered data.
If you really need to visualize all the data, look at Volume visualization in MATLAB documentation. I can recommend SLICE function, for example.
EDIT
Here is an example of full 3D space scatter plot for small vectors (m, n, o equal to 5) with S = rand([m,n,o]); scatter3( X(:), Y(:), Z(:), [], S(:), 'filled' )
EDIT 2
From your comments to the other answer I found that you have 32x76050x4 matrix. You can actually plot 2D slice one at a time. you can do it in 2D with IMAGESC function, or in 3D with SLICE function.
Try:
imagesc(S(:,:,k))
where k is a number from 1 to 4 for the 3rd dimension.
Or try
slice(S, [], [], 1:size(S,3))
shading flat
Maybe this user-created plotting routine can help.
Screnshot from the linked page:
I've always used scatter3 for coloring/sizing pixels in 3d space. I believe the signature is:
scatter3(x,y,z, size, color)
The size and color can be scalar or vector of length equal to the coordinates. I usually use either the color or the size to reflect the fourth attribute, depending on what I'm showing. I don't have Matlab on this machine, so forgive me if my memory isn't completely accurate on the usage. "help scatter3" should describe it much better.
I have multiple vectors of varying lengths that I would like to plot next to each other in 3D space in Matlab.
As an example:
Say I have three vectors:
X is a 5x2 vector,
Y is a 10x2 vector and
Z is a 15x2 vector.
Each element of every vector has the format:
x value, y value
but the x values of the various vectors do not match.
I would like to plot these vectors in 3D space, next to each other. The reason why I don't want to plot them using "hold" is because most of the data have the same values, but I would like to see how many of the plots have the same value at a specific time.
I hope my questions makes sense. Please just ask if anyone is unsure.
I think you are looking for the function ribbon.
Documentation: http://www.mathworks.fr/help/techdoc/ref/ribbon.html
EDIT:
if your x's do not have the same length, you can combine it with interp1 as follow:
x1=0:0.1:1;
x2=0:0.02:1.5;
y1=x1.^2;
y2=sqrt(x2);
y2=interp1(x2,y2,x1);
ribbon(x1',[y1;y2]')