title: How to do a volume rendering of 3D dataset in Mayavi?
body: <p>I have a dataset which is generally 3D image stack. Now I want to display it as a volumetric image by using Mayavi. However, since my spacing of my dataset is not equally spaced in three axis. What should I do to ensure the right spacing. I am trying a simple example with the following codes. but the result still gives me a flat 3D sphere. I am wondering what modify this code.</p>
  <pre><code>import os
  import time
  import matplotlib 
  import numpy as np 
  import matplotlib.pyplot as plt 
  from mayavi import mlab
  import mayavi as myv 
  from tvtk.pyface import light_manager
  from traits.api import HasPrivateTraits, HasTraits, Any, Int, \
      Property, Instance, Event, Range, Bool, Trait, Str
  from tvtk.util import ctf
  
  class MplColorHelper:
      def __init__(self, cmap_name, start_val, stop_val):
          self.cmap_name = cmap_name
          self.cmap = plt.get_cmap(cmap_name)
          self.norm = matplotlib.colors.Normalize(vmin=start_val, vmax=stop_val)
          self.scalarMap = cm.ScalarMappable(norm=self.norm, cmap=self.cmap)
          print(&quot;color clim is {}&quot;.format(self.scalarMap.get_clim()))
      def get_rgb(self, val,alpha):
          return self.scalarMap.to_rgba(val,alpha=alpha,bytes=True)
  
  
  def ChangeVolColormap(vol,cmapName, vmin, vmax, alpha):
      &quot;&quot;&quot;
      Change colormap of mlab volume plot 
      input: 
      : vol: mlab.pipeline.volume return object 
      : cmapName: name, default is 'jet' 
      : vmin, vmax, alpha: parameters for cmap  
      &quot;&quot;&quot;    
      cmapD = MplColorHelper(cmapName,start_val=vmin,stop_val=vmax)
      from tvtk.util.ctf import ColorTransferFunction
      ctf0 = ColorTransferFunction()
      #print(ctf0.__dict__)
      #ctf0.range = (0,255)
      colorValue = np.linspace(vmin,vmax,1024) #np.arange(vmin,vmax,step=0.1,dtype=np.float)
      print(&quot;Num of colormap values is {}&quot;.format(np.size(colorValue)))
      for i in range(np.size(colorValue)):     
          cT = cmapD.get_rgb(colorValue[i],alpha)
          ctf0.add_rgb_point(colorValue[i],cT[0]/255, cT[1]/255, cT[2]/255)  # r, g, and b are float between 0 and 1
      ctf0.nan_color = (0.0,0.0,0.0)
      ctf0.nan_opacity = 1.0 
      above_cT = cmapD.get_rgb(colorValue[-1],alpha)
      below_cT = cmapD.get_rgb(colorValue[0],alpha)
      ctf0.use_above_range_color = False 
      ctf0.use_below_range_color = False
      ctf0.above_range_color = (above_cT[0]/255,above_cT[1]/255,above_cT[2]/255)
      ctf0.below_range_color = (below_cT[0]/255,below_cT[1]/255,below_cT[2]/255)
  
      # save the color transfer function of the current volume
      c = ctf.save_ctfs(vol._volume_property)
      # change the alpha channel as needed
      c['alpha'][1][1] = alpha 
      # load the new color transfer function
      ctf.load_ctfs(c, vol._volume_property)
      vol._volume_property.set_color(ctf0)
      vol._ctf = ctf0
      vol.update_ctf = True
      
      return vol 
  
  def volumeRender(z,x,y,cellVol,rootPath=''):
      f = mlab.figure(bgcolor=(0,0,0),size=(1024,1024))    
      cellVol[cellVol==0] = np.nan 
      
      vmax = np.nanpercentile(cellVol,90)
      vmin = np.nanpercentile(cellVol,10)
  
      cellVolsrc = myv.tools.pipeline.scalar_field(x,y,z,cellVol) 
      cellVolsrc.spacing = [1.0,1.0,1.0]#[0.3/0.0726,0.3/0.0726,1.0]
     
      vol = mlab.pipeline.volume(cellVolsrc,figure=f)
      vol = ChangeVolColormap(vol,cmapName=&quot;Reds&quot;,vmin=vmin,vmax=vmax,alpha=1.0)
      vol.update_pipeline()
      cam = f.scene.camera
      cam.zoom(1.0)
     
      ax = mlab.axes(nb_labels=20,ranges=[np.amin(x),np.amax(x),np.amin(y),np.amax(y),np.amin(z),np.amax(z)])
      ax.axes.label_format = &quot;%.2f&quot;
      ax.label_text_property.font_size = 1
      ax.axes.x_label = &quot;X&quot;
      ax.axes.y_label = &quot;Y&quot;
      ax.axes.z_label = &quot;Z&quot;
      if animateDo:
          ax.axes.visibility = 0
      else:
          ax.axes.visibility = 1
      oax = mlab.orientation_axes(xlabel=&quot;x&quot;,ylabel=&quot;y&quot;,zlabel=&quot;z&quot;) 
      oax._text_property.use_tight_bounding_box = True 
      oax.update_pipeline()
      
  
      mlab.show() 
  
  
      return 1 
  
  if __name__ == &quot;__main__&quot;:
      x = np.arange(0,100,step=0.5) 
      y = np.arange(0,100,step=0.5) 
      z = np.arange(0,50,step=2) 
      x = x - np.mean(x) 
      y = y - np.mean(y) 
      z = z - np.mean(z) 
  
      Z,X,Y = np.meshgrid(z,x,y)
      vol = np.asarray((X**2 + Y**2 + Z**2)&lt;100,dtype=np.float16)*np.random.rand(np.shape(Z)[0],np.shape(Z)[1],np.shape(Z)[2]) * 255
      volumeRender(Z,X,Y,vol) 
  </code></pre>