pythonnumpymatplotlib

How to bind CTRL + scroll to a matplotlib figure?


I want to bind CTRL + scroll inside a matplotlib figure to a zoom function. I know that in matplotlib I can use fig.canvas.mpl_connect('key_press_event', buttonpressed) to bind a certain button to a function (buttonpressed) and use fig.canvas.mpl_connect('scroll_event', scrollused) to bind scrolling to a function (scrollused), but what is the best way to combine this two?

Is there a possibility to bind both combined to a single function call? Or do I have to resort to working around it? For example, setting a variable to true whenever CTRL is pressed and to false whenever it is released again, and checking for this variable in the scroll function call?

The binds can be found here.

Minimal working example of a figure with CTRL bind and scroll bind (but not combined):

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.plot(np.random.rand(10))

def scrolled(event):
    print('scroll used')

def ctrlpressed(event):
    if event.key == 'control':
        print('CTRL pressed')

# Bind to figure
fig.canvas.mpl_connect('key_press_event', ctrlpressed)
fig.canvas.mpl_connect('scroll_event', scrolled)
fig.show()

Solution

  • The best solution I found until now is to bind the ctrl press, the ctrl release, and the scroll separate. The control press sets a check variable to true, the ctrl release sets it to false again. The scroll checks for this variable. In this case the result feels like a ctrl+scroll for the user.

    See code for the example given in the post (the globals are a workaround for this MWE. In my own code I am using an object oriented approach):

    import matplotlib.pyplot as plt
    import numpy as np
    
    fig, ax = plt.subplots()
    ax.plot(np.random.rand(10))
    
    ctrl = False
    
    def scrolled(event):
        global ctrl
        if ctrl:
            print('ctrl+scroll used')
    
    def ctrlpressed(event):
        global ctrl
        if event.key == 'control':
            ctrl = True
    
    def ctrlreleased(event):
        global ctrl
        if event.key == 'control':
            ctrl = False
            
    
    # Bind to figure
    fig.canvas.mpl_connect('key_press_event', ctrlpressed)
    fig.canvas.mpl_connect('key_release_event', ctrlreleased)
    fig.canvas.mpl_connect('scroll_event', scrolled)
    fig.show()