mayavi - setting the [x,y,z] extent of an image programatically

3d, image, mayavi, python, transformation

Solution

Ok, it turns out that this is a known bug in mayavi. However, it is possible to change the orientation, position and scale of an `ImageActor` object after it has been created:

obj = mlab.imshow(img)
obj.actor.orientation = [0, 0, 0]  # the required orientation 
obj.actor.position = [0, 0, 0]     # the required  position 
obj.actor.scale = [0, 0, 0]        # the required scale

Problem

I have some data that consists of several 2D images that I would like to render in specific [x,y,z] positions relative to one another using `mayavi2 (v4.3.0)`. From the documentation it seems that I should just be able to do this with `mlab.imshow()`. Unfortunately, mayavi throws an exception when I call `imshow` specifying the `extent` parameter (`AttributeError: 'ImageActor' object has no attribute 'actor'`). I also tried setting the x,y and z data directly by modifying `im.mlab_source.x,y,z...`. Weirdly, whilst this correctly changes the x and y extents, it does nothing to the z-position even though `im.mlab_source.z` clearly changes. Here's a runnable example: ``` import numpy as np from scipy.misc import lena from mayavi import mlab def normal_imshow(img=lena()): return mlab.imshow(img,colormap='gray') def set_extent(img=lena()): return mlab.imshow(img,extent=[0,100,0,100,50,50],colormap='cool') def set_xyz(img=lena()): im = mlab.imshow(img,colormap='hot') src = im.mlab_source print 'Old z :',src.z src.x = 100*(src.x - src.x.min())/(src.x.max() - src.x.min()) src.y = 100*(src.y - src.y.min())/(src.x.max() - src.y.min()) src.z[:] = 50 print 'New z :',src.z return im if __name__ == '__main__': # this works normal_imshow() # # this fails (AttributeError) # set_extent() # weirdly, this seems to work for the x and y axes, but does not change # the z-postion even though data.z does change set_xyz() ```

Original source