How to find y value of interpolated spline at a desired x value? - scipy

How to extract the y value from spline at a desired x value. For example # x= 0.25
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splev, splrep
x = np.linspace(0, 10, 10)
y = np.sin(x)
spl = splrep(x, y)
x2 = np.linspace(0, 10, 5)
y2 = splev(x2, spl)
plt.plot(x, y, 'o', x2, y2)
plt.show()

Well, you are already doing this by calling splev(x,tck). This outputs an array with the y values at the given x values using the spline described by tck. (In your case, x is given by np.linspace() and tck is the output of np.splrep().)
If you only want to know what the value at e.g. x=.25 is, you would write y3=splev(0.25, spl). Maybe take a look at the documentation for more details: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.splev.html

Related

scipy cubic spline with really large y values

I am doing some lane detection as a fun project and I am trying to create a cubic spline to represent the lane. However, when I use the scipy CubicSpline function I get some absurdly large values.
Here is my code:
from scipy import interpolate
from scipy.interpolate import CubicSpline
from scipy.interpolate import InterpolatedUnivariateSpline
from scipy.interpolate import interp1d
rows = img_size[0] # width
height = left_lane.shape[0]
y_values = [0, height/2, height]
plt.figure()
plt.imshow(left_lane, cmap='gray')
splines = []
particle = particles[0]
cx = [particle[0], particle[1], particle[2]]
cy = [y_values[0], y_values[1], y_values[2]]
points = zip(cx, cy)
points = sorted(points, key=lambda point: point[0])
x1, y1 = zip(*points)
x1 = np.asarray(x1)
y1 = np.asarray(y1)
s = CubicSpline(x1, y1)
new_x = np.arange(min(x1), max(x1), 0.1)
new_y = s(new_x)
plt.plot(new_x, new_y)
plt.show()
Here is the output:
Here is the original image with the control points plotted:
I don't understand why the spline algorithm is giving me such large values for such a simple spline. So, what is the issue here? Bad values? Incorrect usage of cubic spline?
Thank you for the help!
The issue was that the spline is going vertical in this image which means that the x value isn't in always increasing order (e.g. 2nd control > 1st control point). So, when I sorted my lists something like this could happen (2, 1, 3). Then, scipy has to use some huge coefficients to fit this spline.
The fix was to flip the axis so that y is now the x axis. Now the sorting doesn't cause the any weird ordering of the control points.
cx = [particle[0], particle[1], particle[2]]
cy = [y_values[0], y_values[1], y_values[2]]
# Sort particles in increasing x order
points = zip(cx, cy)
points = sorted(points, key=lambda point: point[1])
x1, y1 = zip(*points)
x1 = np.asarray(x1)
y1 = np.asarray(y1)
s = CubicSpline(y1, x1)
new_x = np.arange(min(y1), max(y1), 0.1)
new_y = s(new_x)
plt.plot(new_y, new_x)
plt.plot(cx, cy, '.')

Error in mesh(X,Y,Z) in matlab

This is my code:
load mwe16_2.dat;
x = mwe16_2(:,1); % x contains the 1st column(500 values) of ‘mwe16_2’
y = mwe16_2(:,2); % y contains the 2nd column (500 values)of ‘mwe16_2’
z = mwe16_2(:,3); % z contains the 3rd column(500 values) of ‘mwe16_2’
[X, Y, Z] = meshgrid (x, y, z);
mesh (X, Y, Z)
While running the code it is showing the error:
*Error in plot3_d (line 13) mesh(X,Y,Z) in Matlab*
Can someone say the reason for the error and how to correct it?
[X,Y,Z] = meshgrid(x,y,z) produces three 3D arrays from x, y and z vectors. Now if you take a look at mesh you will see that you are not providing this function with proper input.
If you want to illustrate the set of points defined by three vectors of x, y and z, you can consider using scatter3:
figure; scatter3(x, y, z)

3d-plotting surface 2x^2 + 3y^2 + z^2 = 6

I was trying to plot the above surface in octave/matlab and ran into the this problem.
My code is as follows:
x = linspace(-sqrt(3),sqrt(3),1000);
y = linspace(-sqrt(2),sqrt(2),1000);
z = sqrt(6-2*x.^2-3*y.^2);
surf(x,y,z)
I got the error:
error: mesh: X, Y, Z arguments must be real.
I understand this was because some (x,y)s would result in negative 6-2*x.^2-3*y.*2, but I don't know how to tackle this because I can't trim either part of x or y. Any one can help? Thanks
It depends what you want to do with the non-real values of z.
One thing you could do is to set all these values to zero or NaN (as per #hbaderts' comment):
z = sqrt(6-2*x.^2-3*y.^2);
z( imag(z)~=0 ) = NaN;
One more thing though: your code might have a problem because z is a length-1000 vector, and you want it to be a 1000x1000 matrix. You should use meshgrid() on x and y to get two-dimensional matrices everywhere:
x = linspace(-sqrt(3),sqrt(3),1000);
y = linspace(-sqrt(2),sqrt(2),1000);
[xx,yy] = meshgrid(x,y);
z = sqrt(6-2*xx.^2-3*yy.^2);
z( imag(z)~=0 ) = NaN;
surf(xx,yy,z,'edgecolor','none')
(thanks #LuisMendo for the 'edgecolor','none' suggestion for better visualization.)
Running the above piece of code on octave gives this plot:

MATLAB: Plot 3D surface from irregular data points

Let's say I have a vector of x coordinates, a matrix of y coordinates and corresponding z values:
xcoordinates = [1 2 3 4 5];
ycoordinates = repmat(xcoordinates,5,1)+rand(5,5);
z = zeros(5,5);
for x=xcoordinates
for y=1:5
z(x,y) = sqrt(x^2+ycoordinates(x,y)^2);
end
end
How do I plot a surface determined by the z values at the points given by the corresponding x and y values? The first x value defines the x value for all y values in the first row of the matrix, the second x value to all values in the second row and so on.
(If the answer is griddata I would like some additional pointers. How can I get my data into the correct format?)
mesh(repmat(xcoordinates,5,1), ycoordinates, z)
By the way, you could easily vectorize this computation:
x = repmat(1:5, 5, 1);
y = x + rand(5,5);
z = sqrt(x.^2+y.^2);
mesh(x', y, z)

3D Spline Interpolation Matlab

I have two 3D arrays:
A=[
12751 4616 15915
15864 4622 15667
12877 4683 21050
15816 4668 21253
11374 5006 18495
16995 5466 18493
11638 4880 20023
17078 4938 20006
11576 4886 17011
];
and
B=[
12402 2138 15743
10285 3175 15851
10237 3084 21052
12130 2129 21299
8074 3802 18505
14515 1623 18497
8415 3713 19856
14462 1120 20061
8340 3711 17145
14483 1157 16990];
and I want to do spline or 3D interpolation between them using Interp3 in Matlab.How should I define V in VI = interp3(X,Y,Z,V,XI,YI,ZI)?
Or Y in yy = spline(x,Y,xx).
I don't quite understand your data, is B a function of A (or visa versa)? Also, those arrays appear to be 1D, not 3D. Can you clarify this?
In your function call
yy = spline(x, Y, xx)
Y is the dependent variable which you are interpolating: Y is a function of x and the result of the above function call is to return the value of Y at xx. As an example in one dimension, try
x = linspace(0., 2.*pi, 100);
Y = sin(x);
% What is the value of Y (or sin(x)) at pi/2?
xx = pi/2.;
yy = spline(x, Y, xx); % This should result in yy = 1.000
Check out the spline documentation for more information and examples of using this function.
Now this function is only for 1D fitting, and is (I presume) equivalent to yy = interp1(x, Y, xx, 'spline'). If you want to do a three dimensional lookup, you'll have to use interp3, which generalises the above example to 3D. So rather than just one independent coordinate x, we have two more, y, and z and three coordinates for the point at which we want to perform the look up: xx, yy and zz. The function you are interpolating must be a 3D function of the coordinates (x, y, z). Try, as an example:
x = linspace(-1., 1., 100); y = x; z = x;
[X, Y, Z] = meshgrid(x, y, z);
s = exp(-sqrt(X.^2 + Y.^2 + Z.^2));
sinterp = interp3(x, y, z, s, 0., 0., 0.) % Should give sinterp = 0.9827