2017-03-04 62 views
3

我有一些z=f(x,y)数据,我想绘制。问题是(x,y)不是“好”的矩形的一部分,而是任意的平行四边形,如附图所示(这个特定的一个也是一个矩形,但你可以考虑更一般的情况)。所以我很难弄清楚在这种情况下如何使用plot_surface,因为这通常会将x和y作为二维数组,这里我的x和y值为1d。谢谢。 x,y-DataPython的3D绘图通过非矩形域

+0

您是否事先知道平行四边形图的规格? –

+0

不是真的,我得到的数据,我需要绘制 - 当然我可以从给定的数据计算的规格,我猜... – Faser

+0

你知道数据的顺序? – Eric

回答

5

Abritrary点可以为一维数组被提供给matplotlib.Axes3D.plot_trisurf。他们是否遵循特定的结构并不重要。

这将依赖于数据的结构的其它方法将是

  • 插值定期矩形网格的点。这可以使用griddata完成。见例如here
  • 重塑输入数组,使得他们生活在一个定期,然后用plot_surface()。根据提供点的顺序,对于具有“平行四边形”形状的网格,这可能是一个非常简单的解决方案。
    从上sphere example可以看出,plot_surface()也适用于极不平等的网格形状的情况下,只要在常规的方式真实结构。

下面是一些例子:

enter image description here

为了完整起见,在这里找到产生上面的图像的代码:如果您的数据是为了

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() 
+1

不是'表面'不需要一个矩形网格,它需要的只是一个四边形网格。因此,如果正确重新排列,OP数据可以直接传入“表面”,而不会有任何数字变化。 – Eric

2

,你知道该parallgram的大小,重塑可能足够了:

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

如果平行四边形的每边有10个点,并且点以Z字形排列,将可以工作

+0

谢谢埃里克,你的诀窍也做到了。由于我正在考虑在后期支持具有怪异形状的网格,我现在将使用trisurf。 – Faser

+0

@Faser:您是否生成这些网格?此外,你所说的“网格”而不是“网格”的事实意味着“表面”应该总是足够的 – Eric