I've started using mayavi and I am trying to plot a voxel grid. For this I am using mlab.plot3d to plot each line of the grid, what makes the program very slow since the render has to be called for each line. Is there a way to plot all the lines by calling mlab.plot3d just once ? The main problem is that the lines I am plotting are disconnected, if I put one line after the other in the same array, the render is going to plot connections that I don't want. I've tried to connect the two non-connected lines by putting a None between both lines:
lines = [0.0, 3.0, None, 0.0, 6.0]
But this does not work.
My function to plot the grid line by line can be seen below:
def draw_voxel_grid_bbox_translated(voxel_grid, tube_radius=0.01, color=(0,0,0)):
'''
Draw a bounding box that shows the dimensions of the complete voxel grid in passed color
:param voxel_grid: The voxel grid used to draw the bounding box
:return: None
'''
# Drawing lines parallel to x axis
sense_change_z = 0
for z_step in range(2):
sense_change_y = 0
for y_step in range(2):
if sense_change_y == 0:
xs = [voxel_grid.min_grid_x - voxel_grid.min_grid_x, voxel_grid.max_grid_x - voxel_grid.min_grid_x]
sense_change_y = 1
else:
xs = [voxel_grid.max_grid_x - voxel_grid.min_grid_x, voxel_grid.min_grid_x - voxel_grid.min_grid_x]
sense_change_y = 0
if y_step == 0:
y_coord = voxel_grid.min_grid_y
else:
y_coord = voxel_grid.max_grid_y
if z_step == 0:
z_coord = voxel_grid.min_grid_z
else:
z_coord = voxel_grid.max_grid_z
ys = [y_coord - voxel_grid.min_grid_y, y_coord - voxel_grid.min_grid_y]
zs = [z_coord - voxel_grid.min_grid_z, z_coord - voxel_grid.min_grid_z]
mlab.plot3d(xs, ys, zs, color=color, tube_radius=tube_radius)
# Drawing lines parallel to y axis
for x_step in range(2):
for z_step in range(2):
ys = [voxel_grid.min_grid_y - voxel_grid.min_grid_y, voxel_grid.max_grid_y - voxel_grid.min_grid_y]
if x_step == 0:
x_coord = voxel_grid.min_grid_x
else:
x_coord = voxel_grid.max_grid_x
if z_step == 0:
z_coord = voxel_grid.min_grid_z
else:
z_coord = voxel_grid.max_grid_z
xs = [x_coord - voxel_grid.min_grid_x, x_coord - voxel_grid.min_grid_x]
zs = [z_coord - voxel_grid.min_grid_z, z_coord - voxel_grid.min_grid_z]
mlab.plot3d(xs, ys, zs, color=color, tube_radius=tube_radius)
# Drawing lines parallel to z axis
for x_step in range(2):
for y_step in range(2):
zs = [voxel_grid.min_grid_z - voxel_grid.min_grid_z, voxel_grid.max_grid_z - voxel_grid.min_grid_z]
if x_step == 0:
x_coord = voxel_grid.min_grid_x
else:
x_coord = voxel_grid.max_grid_x
if y_step == 0:
y_coord = voxel_grid.min_grid_y
else:
y_coord = voxel_grid.max_grid_y
xs = [x_coord - voxel_grid.min_grid_x, x_coord - voxel_grid.min_grid_x]
ys = [y_coord - voxel_grid.min_grid_y, y_coord - voxel_grid.min_grid_y]
mlab.plot3d(xs, ys, zs, color=color, tube_radius=tube_radius)
Connecting arbitrary lines between points with one call of points3d is possible and extremely fast. Use following code from the protein example
import mayavi.mlab as mlab
import numpy as np
connections = ((0,2),(3,5)) # point 0 and 2 and 3 and 5 are connected
x = np.random.randn(10)
y = np.random.randn(10)
z = np.random.randn(10)
pts = mlab.points3d(x, y, z)
pts.mlab_source.dataset.lines = np.array(connections)
tube = mlab.pipeline.tube(pts, tube_radius=0.15)
tube.filter.radius_factor = 1.
mlab.pipeline.surface(tube, color=(0.8, 0.8, 0))
mlab.show()