在python中绘制3D矩阵的最佳方法

And*_*rtz 6 python 3d matplotlib

我正在尝试可视化3D数据.这是一个完整的3D矩阵:每个(x,y,z)坐标都有一个值,不同于表面或单个数据向量的集合.我试图这样做的方法是绘制一个不透明的立方体,其中立方体的每个边显示正交维度上的数据总和.

一些示例数据 - 基本上是以(3,5,7)为中心的blob:

import numpy as np
(x,y,z) = np.mgrid[0:10,0:10, 0:10]
data = np.exp(-((x-3)**2 + (y-5)**2 + (z-7)**2)**(0.5))
edge_yz = np.sum(data,axis=0)
edge_xz = np.sum(data,axis=1)
edge_xy = np.sum(data,axis=2)
Run Code Online (Sandbox Code Playgroud)

因此,我们的想法是生成一个显示立方体的3D图; 立方体的每个表面将显示适当的2D矩阵edge_*.这就像在适当的3D位置绘制3个4边多边形(如果你也做了立方体的背面则为6),除了每个多边形实际上是要用颜色绘制的值矩阵.

我目前最好的近似是计算包含偏斜版边缘的较大矩阵,并将这些矩阵连接成一个更大的2D矩阵,并将imshow()表示为更大的矩阵.看起来非常笨拙,并做了很多工作,matplotlib或m3plot中的某些引擎或我确定已经做过的事情.它也只能在单个视角下查看静态图像,但这不是我现在需要克服的.

有没有一种很好的方法可以使用现有的python工具在真正的3D绘图中绘制这些立方体边缘?有没有更好的方法来绘制3D矩阵?

And*_*rtz 5

Falko关于使用contourf的建议有些麻烦。这是有一定局限性的,因为至少我的contourf版本有一些错误,有时它会使其中一个平面在其他平面的前面,但应该在后面,但是现在仅绘制立方体的三个正面或三个背面即可做:

import numpy as np
import math
import matplotlib.pyplot as plot
import mpl_toolkits.mplot3d.axes3d as axes3d

def cube_marginals(cube, normalize=False):
    c_fcn = np.mean if normalize else np.sum
    xy = c_fcn(cube, axis=0)
    xz = c_fcn(cube, axis=1)
    yz = c_fcn(cube, axis=2)
    return(xy,xz,yz)

def plotcube(cube,x=None,y=None,z=None,normalize=False,plot_front=False):
    """Use contourf to plot cube marginals"""
    (Z,Y,X) = cube.shape
    (xy,xz,yz) = cube_marginals(cube,normalize=normalize)
    if x == None: x = np.arange(X)
    if y == None: y = np.arange(Y)
    if z == None: z = np.arange(Z)

    fig = plot.figure()
    ax = fig.gca(projection='3d')

    # draw edge marginal surfaces
    offsets = (Z-1,0,X-1) if plot_front else (0, Y-1, 0)
    cset = ax.contourf(x[None,:].repeat(Y,axis=0), y[:,None].repeat(X,axis=1), xy, zdir='z', offset=offsets[0], cmap=plot.cm.coolwarm, alpha=0.75)
    cset = ax.contourf(x[None,:].repeat(Z,axis=0), xz, z[:,None].repeat(X,axis=1), zdir='y', offset=offsets[1], cmap=plot.cm.coolwarm, alpha=0.75)
    cset = ax.contourf(yz, y[None,:].repeat(Z,axis=0), z[:,None].repeat(Y,axis=1), zdir='x', offset=offsets[2], cmap=plot.cm.coolwarm, alpha=0.75)

    # draw wire cube to aid visualization
    ax.plot([0,X-1,X-1,0,0],[0,0,Y-1,Y-1,0],[0,0,0,0,0],'k-')
    ax.plot([0,X-1,X-1,0,0],[0,0,Y-1,Y-1,0],[Z-1,Z-1,Z-1,Z-1,Z-1],'k-')
    ax.plot([0,0],[0,0],[0,Z-1],'k-')
    ax.plot([X-1,X-1],[0,0],[0,Z-1],'k-')
    ax.plot([X-1,X-1],[Y-1,Y-1],[0,Z-1],'k-')
    ax.plot([0,0],[Y-1,Y-1],[0,Z-1],'k-')

    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plot.show()
Run Code Online (Sandbox Code Playgroud)

plot_front =真实 plot_front =真实 plot_front =假 plot_front =假 其他数据(未显示) 其他数据(未显示)


use*_*537 2

看看MayaVI。contour3d ()函数可能就是您想要的。

这是我对类似问题的回答,其中包含代码示例和结果图/sf/answers/1734913001/