Gráficos 3D de Python sobre un dominio no rectangular

Tengo algunos datos de z=f(x,y) que me gustaría trazar. El problema es que (x,y) no son parte de un rectángulo “bonito”, sino paralelogramos arbitrarios, como se muestra en la imagen adjunta (este en particular también es un rectángulo, pero podría pensar en casos más generales). Por lo tanto, me resulta difícil descubrir cómo puedo usar plot_surface en este caso, ya que esto usualmente tomará xey como arreglos 2d, y aquí mis valores xey son 1d. Gracias. x, y-datos

Los puntos abreviados se pueden suministrar como matrices 1D a matplotlib.Axes3D.plot_trisurf . No importa si siguen una estructura específica.

Otros métodos que dependerían de la estructura de los datos serían

  • Interpolar los puntos en una cuadrícula rectangular regular. Esto se puede lograr usando scipy.interpolate.griddata . Ver ejemplo aquí
  • Cambie la forma de las matrices de entrada de modo que vivan de forma regular y luego use plot_surface() . Dependiendo del orden en que se suministran los puntos, esta podría ser una solución muy fácil para una cuadrícula con forma “paralelogramica”.
    Como puede verse en el ejemplo de la esfera , plot_surface() también funciona en casos de formas de cuadrícula muy desiguales, siempre y cuando esté estructurada de manera regular.

Aquí hay unos ejemplos:

introduzca la descripción de la imagen aquí

Para completar, encuentre aquí el código que produce la imagen anterior:

 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np f = lambda x,y: np.sin(x+0.4*y)*0.23+1 fig = plt.figure(figsize=(5,6)) plt.subplots_adjust(left=0.1, top=0.95,wspace=0.01) ax0 = fig.add_subplot(322, projection="3d") ma = 6*(np.random.rand(100)-0.5) mb = 6*(np.random.rand(100)-0.5) phi = np.pi/4 x = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi) y = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi) z = f(x,y) ax0.plot_trisurf(x,y,z) ax1 = fig.add_subplot(321) ax0.set_title("random plot_trisurf()") ax1.set_aspect("equal") ax1.scatter(x,y, marker="+", alpha=0.4) for i in range(len(x)): ax1.text(x[i],y[i], i , ha="center", va="center", fontsize=6) n = 10 a = np.linspace(-3, 3, n) ma, mb = np.meshgrid(a,a) phi = np.pi/4 xm = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi) ym = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi) shuf = np.c_[xm.flatten(), ym.flatten()] np.random.shuffle(shuf) x = shuf[:,0] y = shuf[:,1] z = f(x,y) ax2 = fig.add_subplot(324, projection="3d") ax2.plot_trisurf(x,y,z) ax3 = fig.add_subplot(323) ax2.set_title("unstructured plot_trisurf()") ax3.set_aspect("equal") ax3.scatter(x,y, marker="+", alpha=0.4) for i in range(len(x)): ax3.text(x[i],y[i], i , ha="center", va="center", fontsize=6) x = xm.flatten() y = ym.flatten() z = f(x,y) X = x.reshape(10,10) Y = y.reshape(10,10) Z = z.reshape(10,10) ax4 = fig.add_subplot(326, projection="3d") ax4.plot_surface(X,Y,Z) ax5 = fig.add_subplot(325) ax4.set_title("regular plot_surf()") ax5.set_aspect("equal") ax5.scatter(x,y, marker="+", alpha=0.4) for i in range(len(x)): ax5.text(x[i],y[i], i , ha="center", va="center", fontsize=6) for axes in [ax0, ax2,ax4]: axes.set_xlim([-3.5,3.5]) axes.set_ylim([-3.5,3.5]) axes.set_zlim([0.9,2.0]) axes.axis("off") plt.savefig(__file__+".png") plt.show() 

Si sus datos están en orden, y conoce el tamaño del diagtwig paralelo, probablemente será suficiente una nueva forma:

 ax.surface(x.reshape(10, 10), y.reshape(10, 10), z.reshape(10, 10)) 

Funcionará si el paralelogramo tiene 10 puntos en cada lado y los puntos están ordenados en un patrón de zigzag