ees
ees

Reputation: 327

Mayavi - picking outside of a imshow() figure's data bounds returns (0,0,0); how to distinguish?

I'm trying to adapt a simple line of code from an official Mayavi example, found at http://docs.enthought.com/mayavi/mayavi/auto/example_pick_on_surface.html.

I want to use the picker command on an imshow() plot instead of the mesh plot in the example; and specifically, I only want those points that are ON the plot (not outside) to be accepted.

However, when I click outside the bounds of my data cells, the value (0,0,0) is returned... How can I distinguish between the user clicking outside the bounds vs. the user actually clicking in the center at (0,0,0)?

import os
import numpy as np
from mayavi import mlab

data = np.random.uniform(0, 2, (450, 450))
fig = mlab.figure(1)
mlab.clf()
landscape = mlab.imshow(data)
cursor3d = mlab.points3d(0., 0., 0., mode='axes',
                                color=(0, 0, 0),
                                scale_factor=0.5)
mlab.title('click me')
mlab.view(90, 0)

def picker_callback2(picker_obj):
    point2d = picker_obj.mapper_position    
    x_, y_, z_ = point2d
    print(x_,y_,z_) #clicks outside data cells return (0,0,0)

fig.on_mouse_pick(picker_callback2)
mlab.show()

UPDATE:

import os
import numpy as np
from mayavi import mlab

data = np.random.uniform(0, 2, (450, 450))
fig = mlab.figure(1)
mlab.clf()
landscape = mlab.imshow(data)
cursor3d = mlab.points3d(0., 0., 0., mode='axes',
                                color=(0, 0, 0),
                                scale_factor=0.5)
mlab.title('click me')
mlab.view(90, 0)

def picker_callback(picker_obj):
    picked = picker_obj.actors
    if landscape.actor.actor._vtk_obj in [o._vtk_obj for o in picked]:
        point2d = picker_obj.mapper_position    
        x_, y_, z_ = point2d
        print(x_,y_,z_) #clicks outside data cells return (0,0,0)

fig.on_mouse_pick(picker_callback)
mlab.show()

Upvotes: 0

Views: 261

Answers (1)

Felipe Lema
Felipe Lema

Reputation: 2718

You're missing the check of objects where we try to match the picked object with the objects we (the user) want to render:

# …
    picked = picker_obj.actors
    if mesh.actor.actor._vtk_obj in [o._vtk_obj for o in picked]:
# …

This is second best answer: use a mesh grid with scalar values to simulate an imshow:

def test_mesh():
    x, y = numpy.mgrid[0:100,0:100]
    z = numpy.zeros_like(x)
    s = numpy.random.rand(*z.shape)
    return mlab.mesh(x, y, z, scalars=s)

_fig = mlab.gcf()
_m = test_mesh()
mlab.view()
def picker_callback(picker):
    picked = picker.actors
    picked_actors=[o for o in picked]
    if _m.actor.actor in picked_actors:
        point2d = picker.mapper_position    
        x_, y_, z_ = point2d
        print(x_,y_,z_)

_fig.on_mouse_pick(picker_callback)
mlab.show()

Upvotes: 1

Related Questions