Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 14331

3D interpolation of data in python limiting the fitted function to only be increasing in z

$
0
0

I have the following data:

x = array([ 0, 0.08885313,  0.05077321,  0.05077321,  0.03807991,  0.03807991,        0.03807991,  0.02538661,  0.02538661,  0.0126933 ,  0.0126933 ,       -0.        , -0.        , -0.0126933 , -0.0126933 , -0.02538661,       -0.02538661, -0.02538661, -0.03807991, -0.05077321, -0.05077321,       -0.05077321, -0.06346652, -0.07615982, -0.11423973, -0.12693304,       -0.13962634])y = array([ 0, -0.15231964, -0.08885313, -0.17770625, -0.08885313, -0.10154643,       -0.12693304, -0.07615982, -0.08885313, -0.07615982, -0.08885313,       -0.07615982, -0.10154643, -0.08885313, -0.10154643, -0.07615982,       -0.08885313, -0.17770625, -0.10154643, -0.08885313, -0.11423973,       -0.12693304, -0.10154643, -0.08885313, -0.17770625, -0.12693304,       -0.11423973])z = array([ 0, 1.21839241, 0.78673339, 1.21839241, 0.70318648, 0.82850684,       0.96078945, 0.64748854, 0.71014872, 0.63356406, 0.71711096,       0.65445078, 0.77977115, 0.73103545, 0.77977115, 0.68926199,       0.73799769, 1.19750569, 0.85635581, 0.84243133, 0.96078945,       1.02344963, 0.93294048, 0.97471393, 1.24624138, 1.20446793,       1.22535466])

I have used the following code which fits a surface in the form of points in the (x, y, z) space to my data.

# Find the maximum and minimum x valuesi_max, = np.where(np.isclose(x, np.max(x)))i_min, = np.where(np.isclose(x, np.min(x)))x_max = x[i_max][0]x_min = x[i_min][0]# Find the corresponding y values (i.e. y values of those points where x is maximum)y_max = y[i_max][0]y_min = y[i_min][0]# Function finding 2D-line coefficients, based on this answer https://stackoverflow.com/a/21566184/3715182def line_coeffs(points):    x_coords, y_coords = zip(*points)    A = vstack([x_coords, ones(len(x_coords))]).T    # y = a*x + b    a, b = lstsq(A, y_coords, rcond=None)[0]    return (a, b)# Find coefficients of the two lines "limiting" all points left and right across the x-axis in the XY-planek1_max, k2_max = line_coeffs([(x_max, y_max), (0, 0)])k1_min, k2_min = line_coeffs([(x_min, y_min), (0, 0)])# Define mathematical function for curve fitting def func(xy, a, b, c, d, e, f):    x, y = xy    return a + b*x + c*y + d*x**2 + e*y**2 + f*x*y# Create a grid of points over the surfacex_fill = np.linspace(-0.2, 0.2, 40)y_fill = np.linspace(-0.3, 0, 40)X_fill, Y_fill = np.meshgrid(x_fill, y_fill)# Evaluate the function at each point on the surfaceZ_fill = func((X_fill, Y_fill), *popt)# Plot the data points and the filled surfacefig = plt.figure()ax = fig.add_subplot(111, projection='3d')ax.scatter(x, y, z, color='blue', label='Data Points')ax.scatter(np.where(X_fill >= (Y_fill - k2_min)/k1_min, np.where(X_fill <= (Y_fill - k2_max)/k1_max, X_fill, np.nan), np.nan), Y_fill, Z_fill, color='red', alpha=0.5, s= 2)ax.set_xlim([-0.2, 0.2])ax.set_ylim([-0.3, 0.2])ax.set_zlim([0, 1.2])ax.set_xlabel('x')ax.set_ylabel('y')ax.set_zlabel('z')plt.show()

This gives my the following result:

enter image description here

You can see that the red points fit my blue data points well. However, I would be expected the data to continue upwards rather than going back down around y=-0.3. How can I limit (or change) my fitting function so that the function is continuously increasing in z. I would expect something a bit more like a section of the following plot (only between 2 angles):

enter image description here


Viewing all articles
Browse latest Browse all 14331

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>