I would like to have a 3d plot with matplotlib.
我想用matplotlib绘制一个3d图。
Data are the following: I have a matrix with each row containing Y coordinates for the 3d plot. Each row first elements are the X coordinates for the 3d plot. Finally, a second matrix contains high for each point, at a X,Y position. This second matrix thus contains my Z coordinates. Both matrices are arrays of arrays with Python. I would like to know how to transform data so as to obtain:
数据如下:我有一个矩阵,每一行包含3d绘图的Y坐标。每一行的第一个元素都是三维图的X坐标。最后,第二个矩阵包含每个点在X Y位置的高值。这第二个矩阵包含了我的Z坐标。这两个矩阵都是带有Python的数组。我想知道如何转换数据以获得:
- a plot of each 1d signal corresponding to an X, like this (photo available online)
- 每个对应于X的1d信号的图,如图所示
- a wireframe plot for same data, like this
- 对相同数据的线框图,像这样
I have written an helper function for a wireframe work,
我写了一个线框图的辅助函数,
######## HELPER FOR PLOT 3-D
def plot_3d(name,X,Y,Z):
fig = plt.figure(name)
ax = fig.gca(projection='3d')
X = np.array(X)
Y = np.array(Y)
Z = np.array(Z)
ax.plot_wireframe(X,Y,Z,rstride=10,cstride=10)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
but I dont know how to transform data X,Y,Z to make them fit requirements for matplotlib function, which want 2D lists for X, Y ,Z.
但是我不知道如何转换数据X,Y,Z,使它们符合matplotlib函数的要求,它需要2D的X,Y,Z的列表。
For first graph, I read help, and want to use 2d plot in 3d. Example source code gives:
对于第一个图形,我阅读了help,并想使用2d的3d绘图。示例的源代码给:
x = np.linspace(0, 1, 100)
y = np.sin(x * 2 * np.pi) / 2 + 0.5
ax.plot(x, y, zs=0, zdir='z', label='zs=0, zdir=z')
where z is the constant coordinate. In my case, x is the constant coordinate. I adapt with
z是常数坐标。在我的例子中,x是常数坐标。我适应
fig = plt.figure('2d profiles')
ax = fig.gca(projection='3d')
for i in range(10):
x = pt ## this is a scalar
y = np.array(y)
z = np.array(z)
ax.plot(xs = x, y, z, xdir='x')
plt.show()
but there is warning: non-keyword arg after keyword arg
. How to fix?
但是有一个警告:关键词arg后面有非关键词arg。如何修复?
Thanks and regards
感谢和问候
1 个解决方案
#1
0
Regarding the display of a serie of vectors in 3D, I came with following 'almost working' solution:
关于3D显示的一系列矢量,我有以下“几乎可以工作”的解决方案:
def visualizeSignals(self, imin, imax):
times = self.time[imin:imax]
nrows = (int)((times[(len(times)-1)] - times[0])/self.mod) + 1
fig = plt.figure('2d profiles')
ax = fig.gca(projection='3d')
for i in range(nrows-1):
x = self.mat1[i][0] + self.mod * i
y = np.array(self.mat1T[i])
z = np.array(self.mat2[i])
ax.plot(y, z, zs = x, zdir='z')
plt.show()
As for 2D surface or meshgrid plot, I come through using meshgrid. Note that you can reproduce a meshgrid by yourself once you know how a meshgrid is built. For more info on meshgrid, I refer to this post.
对于二维平面或网格图,我是通过网格网格来实现的。注意,一旦您知道网格是如何构建的,您就可以自己复制网格。关于网格的更多信息,我参考这篇文章。
Here is the code (cannot use it as such since it refers to class members, but you can build your code based on 3d plot methods from matplotlib I am using)
这里是代码(由于它引用了类成员,所以不能这样使用它,但是您可以基于我正在使用的matplotlib的3d绘图方法构建代码)
def visualize(self, imin, imax, typ_ = "wireframe"):
"""
3d plot signal between imin and imax
. typ_: type of plot, "wireframce", "surface"
"""
times = self.retT[imin:imax]
nrows = (int)((times[(len(times)-1)] - times[0])/self.mod) + 1
self.modulate(imin, imax)
fig = plt.figure('3d view')
ax = fig.gca(projection='3d')
x = []
for i in range(nrows):
x.append(self.matRetT[i][0] + self.mod * i)
y = []
for i in range(len(self.matRetT[0])):
y.append(self.matRetT[0][i])
y = y[:-1]
X,Y = np.meshgrid(x,y)
z = [tuple(self.matGC2D[i]) for i in range(len(self.matGC))] # matGC a matrix
zzip = zip(*z)
for i in range(len(z)):
print len(z[i])
if(typ_ == "wireframe"):
ax.plot_wireframe(X,Y,zzip)
plt.show()
elif(typ_ == "contour"):
cset = ax.contour(X, Y, zzip, zdir='z', offset=0)
plt.show()
elif(typ_ == "surf_contours"):
surf = ax.plot_surface(X, Y, zzip, rstride=1, cstride=1, alpha=0.3)
cset = ax.contour(X, Y, zzip, zdir='z', offset=-40)
cset = ax.contour(X, Y, zzip, zdir='x', offset=-40)
cset = ax.contour(X, Y, zzip, zdir='y', offset=-40)
plt.show()
#1
0
Regarding the display of a serie of vectors in 3D, I came with following 'almost working' solution:
关于3D显示的一系列矢量,我有以下“几乎可以工作”的解决方案:
def visualizeSignals(self, imin, imax):
times = self.time[imin:imax]
nrows = (int)((times[(len(times)-1)] - times[0])/self.mod) + 1
fig = plt.figure('2d profiles')
ax = fig.gca(projection='3d')
for i in range(nrows-1):
x = self.mat1[i][0] + self.mod * i
y = np.array(self.mat1T[i])
z = np.array(self.mat2[i])
ax.plot(y, z, zs = x, zdir='z')
plt.show()
As for 2D surface or meshgrid plot, I come through using meshgrid. Note that you can reproduce a meshgrid by yourself once you know how a meshgrid is built. For more info on meshgrid, I refer to this post.
对于二维平面或网格图,我是通过网格网格来实现的。注意,一旦您知道网格是如何构建的,您就可以自己复制网格。关于网格的更多信息,我参考这篇文章。
Here is the code (cannot use it as such since it refers to class members, but you can build your code based on 3d plot methods from matplotlib I am using)
这里是代码(由于它引用了类成员,所以不能这样使用它,但是您可以基于我正在使用的matplotlib的3d绘图方法构建代码)
def visualize(self, imin, imax, typ_ = "wireframe"):
"""
3d plot signal between imin and imax
. typ_: type of plot, "wireframce", "surface"
"""
times = self.retT[imin:imax]
nrows = (int)((times[(len(times)-1)] - times[0])/self.mod) + 1
self.modulate(imin, imax)
fig = plt.figure('3d view')
ax = fig.gca(projection='3d')
x = []
for i in range(nrows):
x.append(self.matRetT[i][0] + self.mod * i)
y = []
for i in range(len(self.matRetT[0])):
y.append(self.matRetT[0][i])
y = y[:-1]
X,Y = np.meshgrid(x,y)
z = [tuple(self.matGC2D[i]) for i in range(len(self.matGC))] # matGC a matrix
zzip = zip(*z)
for i in range(len(z)):
print len(z[i])
if(typ_ == "wireframe"):
ax.plot_wireframe(X,Y,zzip)
plt.show()
elif(typ_ == "contour"):
cset = ax.contour(X, Y, zzip, zdir='z', offset=0)
plt.show()
elif(typ_ == "surf_contours"):
surf = ax.plot_surface(X, Y, zzip, rstride=1, cstride=1, alpha=0.3)
cset = ax.contour(X, Y, zzip, zdir='z', offset=-40)
cset = ax.contour(X, Y, zzip, zdir='x', offset=-40)
cset = ax.contour(X, Y, zzip, zdir='y', offset=-40)
plt.show()