Pick

class vtkplotlib.interactive.pick(style, from_=None)[source]

Pick collects information about user interactions into a handy bucket class.

import vtkplotlib as vpl
import numpy as np

# Create a figure.
fig = vpl.figure()

# With something semi-interesting in it.
u, v = np.meshgrid(np.linspace(-10, 10), np.linspace(-10, 10))
vpl.surface(np.sin(u) * np.sin(v), np.cos(u) * np.sin(v), v, scalars=v)

def callback(invoker, event_name):
    vpl.i.call_super_callback()

    # Optional, if you're using Python in interactive mode then you can
    # play around with the pick afterwards.
    global pick

    # pick this current event to get a pick object. A pick contains
    # everything VTK has to tell you about the event.
    pick = vpl.i.pick(invoker)

    # To see everything pick has to say, just print it.
    print(pick)

    if pick.actor is None:
        print("Mouse is hovering over background.")
    else:
        print("Mouse is hovering over {} at (x, y, z) = {}."
              .format(repr(pick.actor), pick.point))

fig.style.AddObserver("MouseMoveEvent", callback)

vpl.show()

The most important properties of a pick are pick.point which tells you the 3D coordinates of the event and pick.actor which tells you the vtkActor of the plot under which the event took place.

property actor

The vtkActor of the plot where the event took place. This corresponds to plot.actor where plot is the output of any vtkplotlib plotting function.

import vtkplotlib as vpl
import numpy as np

fig = vpl.figure()
spheres = vpl.scatter(np.random.uniform(-10, 10, (30, 3)))
vpl.text("Hover the mouse over a sphere")

def callback(invoker, event_name):
    actor = vpl.i.pick(invoker).actor
    for sphere in spheres:
        if sphere.actor is actor:
            sphere.color = "blue"
        else:
            sphere.color = "white"
    vpl.i.call_super_callback()
    fig.update()

fig.style.AddObserver("MouseMoveEvent", callback)

fig.show()
property from_

Limit the actor results to only a set of actors.

The (writeable) from_ attribute allows you restrict the actors that can be picked. This can be useful, when placing markers on an object, to avoid placing a marker on top of another marker.

You can set this attribute to an iterable of vtkplotlib plots, an iterable of vtkActors, or a mapping with either plots or actors as its keys. On setting this attribute is normalised into the mapping form. To disable filtering use either del pick.from_ or pick.from_ = None.

import vtkplotlib as vpl
import numpy as np

fig = vpl.figure()
ball = vpl.scatter([0, 0, 0], radius=10, color="green")
text = vpl.text("Click on the green ball", color="black")

# Create a restricted pick that will only treat clicks on anything
# other than the ball as it would with clicks on the background.
pick = vpl.i.pick(fig, from_=[ball])

def callback(pick):
    # We're going to use OnClick() instead of fig.style.AddObserver()
    # so this callback should only take a `pick` argument.
    if pick.actor is not None:
        vpl.scatter(pick.point, color="r", fig=fig)
        text.text = "Now try to click on one of the red balls"

# OnClick is more suitable for capturing mouse clicks because it can
# differentiate between a click and a click-and-drag. See the reference
# for OnClick().
vpl.i.OnClick("Left", fig, callback, pick=pick)

fig.show()

If its not immediately clear what the difference is then remove the from_=[ball] try clicking on a red ball a few times, then rotate the camera slightly. You should see that each click creates a new red ball on top of the last, creating a tower of balls.

property key_modifiers

key_modifiers lists currently held down modifiers keys.

The result can be any combination of ("Shift", "Control", "Alt"). The order is consistent, meaning that it is safe to use something like the following:

if pick.key_modifiers == ("Shift", "Alt"):

There is not Super key in VTK.

property key_name

key_name is used to capture keyboard interaction.

import vtkplotlib as vpl

fig = vpl.figure()
vpl.quick_test_plot()

# The repr tells you everything there is to know...
callback = lambda *spam: print(vpl.i.pick(fig))

# Attach to either 'KeyPressEvent' or 'KeyReleaseEvent'.
fig.style.AddObserver("KeyPressEvent", callback)
fig.show()

There is also a similar key_text attribute. The key_text is usually the single character typed when a given key is pressed. If pressing that key doesn’t normally type anything (e.g. pressing shift) then key_text is empty. key_name is always defined. The following table shows the differences between the two.

Action

key_name

key_text

Press ‘a’ key

'a'

'a'

Press Shift a

'A'

'A'

Press Shift key

'Shift_L'

''

Press Return key

'return'

'\r'

Press F5 key

'F5'

''

Press ‘#’ key

'numbersign'

'#'

Press ‘?’ key

'question'

'?'

Type unicode Á

'a'

''

Note

Unlike with every other event, there is no need to use call_super_callback(). It is called implicitly.

property key_text

key_text is used to capture keyboard interaction. See key_name for more information.

property picked

Contains the plot where the event happened. This can be thought of as equivalent to pick.from_[pick.actor]. If the from_ has not been set or the event happened over empty space or over an actor which isn’t in pick.from_ then the output is None.

import vtkplotlib as vpl
import numpy as np

fig = vpl.figure()
spheres = vpl.scatter(np.random.uniform(-30, 30, (50, 3)))
vpl.text("Click on the spheres")

def callback(pick):
    sphere = pick.picked
    if sphere is not None:
        sphere.color = np.random.random(3)

vpl.i.OnClick("Left", fig, callback, pick=vpl.i.pick(fig, from_=spheres))

fig.show()
property point

A 3D coordinates tuple of where the event took place. If the event happened over empty background or a 2D plot such as a vtkplotlib.scalar_bar() then outputs a 3-tuple of nans. To check for this use pick.actor_3D is None.

The coordinates interpolate between vertices you have provided. If you require the nearest user-provided coordinate then you must implement this yourself. See Looking up original data.

property point_2D

The 2D (horizontal, vertical) coordinates in pixels where the event happened. (0, 0) is the left lower corner of the window.