Interpolar los valores de Z en una superficie 3D, a partir de un conjunto irregular de puntos

Tengo una superficie que se parece a la Figura A, imagino que es una vista desde arriba. La superficie ha calculado el valor z.

introduzca la descripción de la imagen aquí

Ahora necesito encontrar todos los valores de Z en puntos nuevos como la figura B. ¿Cómo hacer esto? Intenté scipy.interpolate.interp2d pero da algunos resultados extraños como este: introduzca la descripción de la imagen aquí

Solo quiero encontrar z personalizada para x e y personalizadas dentro de la “figura”.

Ejemplo de código mínimo

 func_int = scipy.interpolate.interp2d([point[0] for point in pointsbottom],[point[1] for point in pointsbottom],[point[2] for point in pointsbottom], kind = 'linear') pointscaption = map(lambda point:(point[0],point[1],func_int(point[0],point[1])),pointscaption) 

Donde pointsbottom es la lista de (x, y, z) y pointscaption es la lista de (x, y, z) pero necesito encontrar una nueva z.

Trate de usar griddata en su lugar:

  grid_z1 = griddata(points, values, (grid_x, grid_y), method='linear') 

La diferencia es que griddata espera datos regulares como entrada (hmm …, creo). No es que debas tener un resultado diferente, sino que podrás detectar el problema más rápido. Puede enmascarar los datos de la “cuadrícula regular” fácilmente.

Mi primera conjetura sería que esas coordenadas de entrada no son lo que usted espera que sean (tal vez con una escala diferente de la función que está calculando), pero es difícil decirlo sin probarlas.

En cualquier caso, parece que desea una superficie, que por definición es un tipo de datos de cuadrícula, por lo que debería ser bastante fácil detectar el problema utilizando este marco diferente.

EDITAR (más consideraciones sobre las dudas del cartel):

Digamos que desea algún objeto en el que desea introducir algunos datos dentro. Después de hacer esto, desea poder estimar cualquier posición utilizando esos datos. Para eso puedes construir una clase como esta:

  import numpy as np class Estimation(): def __init__(self,datax,datay,dataz): self.x = datax self.y = datay self.v = dataz def estimate(self,x,y,using='ISD'): """ Estimate point at coordinate x,y based on the input data for this class. """ if using == 'ISD': return self._isd(x,y) def _isd(self,x,y): d = np.sqrt((x-self.x)**2+(y-self.y)**2) if d.min() > 0: v = np.sum(self.v*(1/d**2)/np.sum(1/d**2)) return v else: return self.v[d.argmin()] 

Este ejemplo utiliza el método de la distancia al cuadrado inverso que es muy estable para la estimación (si evita las divisiones por cero). No será rápido pero espero que sea comprensible. Desde este punto en adelante, puede estimar cualquier punto en el espacio 2D haciendo:

  e = Estimation(datax,datay,dataz) newZ = e.estimate(30,55) # the 30 and 55 are just example coordinates 

Si tuvieras que hacer esto a una cuadrícula completa:

  datax,datay = np.random.randint(0,100,10),np.random.randint(0,100,10) dataz = datax/datay e = Estimation(datax,datay,dataz) surf = np.zeros((100,100)) for i in range(100): for j in range(100): surf[i,j] = e.estimate(i,j) 

Obtendría una imagen que puede ver usando, por ejemplo, matplotlib (en la que el color representa la altura de su superficie):

  import matplotlib.pyplot as plt plt.imshow(surf.T,origin='lower',interpolation='nearest') plt.scatter(datax,datay,c=dataz,s=90) plt.show() 

El resultado de este experimento es este:

Superficie estimada

Si no desea utilizar ISD (Distancia cuadrada inversa) simplemente implemente un nuevo método en la clase de estimación. ¿Es esto lo que estás buscando?