Alright so guys I have this 3d array of 1's and 0's which is supposed to represent a 3d object. 0 means that there is nothing there. 1 means that the objects exists in that co-ordinate. I need to display the 3d-object on my screen. It would be ideal for me to have a discrete 3 dimensoinal graph with value depending colors. I tried looking into glumpy and vispy but the documentation page seems to be down right now.
-
A good answer will depend on the type of visualization you need (slices, volume, etc.). In any case for high level visualization you can consider: VTK, Mayavi, PyQtGraph. Vispy and Glumpy probably already have some kind of volume view so I would consider both a possibility. Other than those check if Galry also has something like this.armatita– armatita2017-06-29 12:47:41 +00:00Commented Jun 29, 2017 at 12:47
-
Just an extra. Blender can also be used to do this. You can use Python, including numpy, inside blender itself. Check this question.armatita– armatita2017-06-29 12:51:28 +00:00Commented Jun 29, 2017 at 12:51
-
What do you mean by "value depending colors"? Surely whether or not the point appears in 3D is dependent on the value. Do you mean dependent on the index?Tom Wyllie– Tom Wyllie2017-06-29 13:34:46 +00:00Commented Jun 29, 2017 at 13:34
-
See this answer for the options you have using matplotlib.ImportanceOfBeingErnest– ImportanceOfBeingErnest2018-03-24 11:25:38 +00:00Commented Mar 24, 2018 at 11:25
-
The problem has been solved.rjpj1998– rjpj19982018-03-25 08:23:52 +00:00Commented Mar 25, 2018 at 8:23
3 Answers
I made a pull request to matplotlib that does exactly this, adding the ax3d.voxels function. Unfortunately, it hasn't been reviewed fully yet.
Update: This made it into matplotlib 2.1
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# your real data here - some 3d boolean array
x, y, z = np.indices((10, 10, 10))
voxels = (x == y) | (y == z)
ax.voxels(voxels)
plt.show()

9 Comments
voxels(ax3d, ...) instead of ax3d.voxelsUse np.where to extract the coordinates, and matplotlib for the 3D plot.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
data = np.zeros(shape=(20, 20, 20), dtype=np.bool_)
np.fill_diagonal(data, True)
fig = plt.figure()
Axes3D(fig).plot_wireframe(*np.nonzero(data))
plt.show()
This plots a basic 3D wireframe according to where the ones appeared in the matrix. You may wish to use plot_surface or scatter in place of plot_wireframe. See the documentation for more information.
5 Comments
np.where taking a long time? I would be very surprised if that was the case. Matplotlib, however, is a pile of garbage so I would not be surprised if the rendering of the 3D plot is very slow. You may wish to look into renderring it without popping up the windows and just saving the images as files, but other than that I'm afraid I have no better suggestions.data[8:12,8:12,8:12] = 1 after the current initializationwireframe doesn't do the right thing. OP's exact use case is not clear and I felt this was the most likely to be suitable, but of course isn't a perfect solution hence why I listed scatter and plot_surface as possible alternatives. Seems like the solution from your PR is the best one though. I'll edit this answer once that's merged.Could you save the x,y,z coordinates of each '1' point to a file and display it with cloudcompare or meshlab?
Cloudcompare will even let you store other values after each point and choose how to map these onto colour