2

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.

5
  • 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. Commented 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. Commented 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? Commented Jun 29, 2017 at 13:34
  • See this answer for the options you have using matplotlib. Commented Mar 24, 2018 at 11:25
  • The problem has been solved. Commented Mar 25, 2018 at 8:23

3 Answers 3

6

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

resulting plot

Sign up to request clarification or add additional context in comments.

9 Comments

Damn, gonna have to wait then?
You can always include the function there in your own code, using voxels(ax3d, ...) instead of ax3d.voxels
Man I am a complete noob with matplotlib. Could you redirect me to a detailed guide?
A detailed guide to using the function from that pull request? Just copy and paste the function from the diff
if i dont send an error I get: File "3d.py", line 30, in voxels color = next(self._get_patches_for_fill.prop_cycler)['color'] AttributeError: type object 'Axes3D' has no attribute '_get_patches_for_fill' And if i send colors, I get: self.xy_dataLim.update_from_data_xy(np.array([x, y]).T, not had_data) AttributeError: 'list' object has no attribute 'xy_dataLim'
|
1

Use 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

I dont have to use numpy.where because my array already only has 1's and 0's. while it looks like its working for the most part, can you recommend me something more faster, this is way too laggy.
Is 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.
This doesn't do the right thing, does it? Doesn't it just plot a line through every point in the mesh in scanline order? Try it with data[8:12,8:12,8:12] = 1 after the current initialization
Also, I've edited your answer to use boolean arrays - feel free to revert, but it seemed easier than explaining in the comments
You're right @Eric, wireframe 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.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.