2017-03-05 4 views
2

In Python, gegeben eine N_1 x N_2 x N_3 Matrix, die entweder 0s oder 1s enthält, würde ich nach einer Möglichkeit suchen, die Daten in 3D als N_1 x N_2 x N_3 Volumen mit Volumenpixel (Voxel) an der Stelle von 1s anzuzeigen.Darstellen von Voxeln mit Matplotlib

Zum Beispiel, wenn die Koordinaten von 1s [[1, 1, 1], [4, 1, 2], [3, 4, 1]], würde die gewünschte Ausgabe wie folgt aussehen

Es scheint, dass das mplot3D Modul von matplotlib das Potenzial, um dies zu erreichen haben könnte, aber ich haven Ich habe kein Beispiel für diese Art von Handlung gefunden. Würde jemand eine einfache Lösung kennen, um dieses Problem anzugehen?

Vielen Dank im Voraus für Ihre Hilfe.

Antwort

2

Durch die Anpassung eines Codes von this answer (der teilweise auf this answer basiert) kann man Quader einfach als surface plots darstellen.

Man kann dann über das Eingabearray iterieren und beim Finden eines 1 einen Quader an der Position zeichnen, die den Arrayindizes entspricht.

from mpl_toolkits.mplot3d import Axes3D 
import numpy as np 
import matplotlib.pyplot as plt 

def cuboid_data(pos, size=(1,1,1)): 
    # code taken from 
    # https://stackoverflow.com/a/35978146/4124317 
    # suppose axis direction: x: to left; y: to inside; z: to upper 
    # get the (left, outside, bottom) point 
    o = [a - b/2 for a, b in zip(pos, size)] 
    # get the length, width, and height 
    l, w, h = size 
    x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]], 
     [o[0], o[0] + l, o[0] + l, o[0], o[0]], 
     [o[0], o[0] + l, o[0] + l, o[0], o[0]], 
     [o[0], o[0] + l, o[0] + l, o[0], o[0]]] 
    y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]], 
     [o[1], o[1], o[1] + w, o[1] + w, o[1]], 
     [o[1], o[1], o[1], o[1], o[1]],   
     [o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]] 
    z = [[o[2], o[2], o[2], o[2], o[2]],      
     [o[2] + h, o[2] + h, o[2] + h, o[2] + h, o[2] + h], 
     [o[2], o[2], o[2] + h, o[2] + h, o[2]],    
     [o[2], o[2], o[2] + h, o[2] + h, o[2]]]    
    return x, y, z 

def plotCubeAt(pos=(0,0,0),ax=None): 
    # Plotting a cube element at position pos 
    if ax !=None: 
     X, Y, Z = cuboid_data(pos) 
     ax.plot_surface(X, Y, Z, color='b', rstride=1, cstride=1, alpha=1) 

def plotMatrix(ax, matrix): 
    # plot a Matrix 
    for i in range(matrix.shape[0]): 
     for j in range(matrix.shape[1]): 
      for k in range(matrix.shape[2]): 
       if matrix[i,j,k] == 1: 
        # to have the 
        plotCubeAt(pos=(i-0.5,j-0.5,k-0.5), ax=ax)    

N1 = 10 
N2 = 10 
N3 = 10 
ma = np.random.choice([0,1], size=(N1,N2,N3), p=[0.99, 0.01]) 

fig = plt.figure() 
ax = fig.gca(projection='3d') 
ax.set_aspect('equal') 

plotMatrix(ax, ma) 

plt.show() 

enter image description here

+0

Vielen Dank für diese schnelle und präzise Antwort! – Learn12

+0

Ich habe eine [PR hier] (https://github.com/matplotlib/matplotlib/pull/6404) gemacht, die diese Funktionalität als 'ax.voxels (matrix) 'in matplotlib hinzufügt, mit der Eigenschaft, interne Flächen wegzulassen – Eric

2

Die anstende matplotlib Version 2.1 hat eine Funktion haben und examples for 3D voxels.

Wenn Sie Anaconda verwenden, können Sie es über den Conda-Forge-Kanal installieren.

conda install -c conda-forge matplotlib 
Verwandte Themen