Analysis of matplotlib toolbar source code III (adding and deleting custom tool items)

Turn:

Analysis of matplotlib toolbar source code III (adding and deleting custom tool items)

Matplotlib toolbar source code analysis II (adding and deleting built-in tool items) discusses the management of built-in tool items in toolbars. In addition to built-in tool items, custom tool items are required in many scenarios. The official gives a case https://matplotlib.org/gallery/user_interfaces/toolmanager_sgskip.html , mainly based on Matplotlib backend_ managers. The toolmanager class is implemented by using the toolbar manager mode.

Official case analysis

The key points of the official case are explained below.

import matplotlib.pyplot as plt
# Set toolbar to use toolbar manager mode
plt.rcParams['toolbar'] = 'toolmanager'
# The base classes ToolBase and ToolToggleBase of the imported tool item
from matplotlib.backend_tools import ToolBase, ToolToggleBase

# Because a tool item must be added in the form of a class, a user-defined basic tool item class is created, and the base class is ToolBase
class ListTools(ToolBase):
    # The function of this tool item is to list all tool items managed by the toolbar manager
    """List all the tools controlled by the `ToolManager`."""
    # Set default shortcut keys and tool item descriptions
    default_keymap = 'm'
    description = 'List Tools'
    
    # Defines the action when a tool item is triggered
    def trigger(self, *args, **kwargs):
        print('_' * 80)
        print("{0:12} {1:45} {2}".format(
            'Name (id)', 'Tool description', 'Keymap'))
        print('-' * 80)
        # Gets all tool items managed by the toolbar manager
        tools = self.toolmanager.tools
        # Output each tool item
        for name in sorted(tools):
            if not tools[name].description:
                continue
            keys = ', '.join(sorted(self.toolmanager.get_tool_keymap(name)))
            print("{0:12} {1:45} {2}".format(
                name, tools[name].description, keys))
        print('_' * 80)
        print("Active Toggle tools")
        print("{0:12} {1:45}".format("Group", "Active"))
        print('-' * 80)
        for group, active in self.toolmanager.active_toggle.items():
            print("{0:12} {1:45}".format(str(group), str(active)))

# Create a user-defined switching tool item based on ToolToggleBase. When triggered, the switching tool item will switch between effective and invalid states
class GroupHideTool(ToolToggleBase):
    # The function of this tool item is to switch between displaying / hiding data elements according to groups
    """Show lines with a given gid."""
    #  Set default shortcut keys and tool item descriptions
    default_keymap = 'G'
    description = 'Show by gid'
    default_toggled = True
    
    # The parameter gid of the constructor is the grouping of data elements
    def __init__(self, *args, gid, **kwargs):
        self.gid = gid
        super().__init__(*args, **kwargs)
    # Define the method when the tool item takes effect
    def enable(self, *args):
        self.set_lines_visibility(True)
    # Define the method when the tool item fails
    def disable(self, *args):
        self.set_lines_visibility(False)

    def set_lines_visibility(self, state):
        for ax in self.figure.get_axes():
            for line in ax.get_lines():
                if line.get_gid() == self.gid:
                    line.set_visible(state)
        # be careful! After the image is generated, the elements in the modified image must be redrawn
        self.figure.canvas.draw()


fig = plt.figure()
# Note that data elements can be grouped through the gid attribute
plt.plot([1, 2, 3], gid='mygroup')
plt.plot([2, 3, 4], gid='unknown')
plt.plot([3, 2, 1], gid='mygroup')

# Add the custom item to the tool item manager as the name of the tool item
fig.canvas.manager.toolmanager.add_tool('List', ListTools)
fig.canvas.manager.toolmanager.add_tool('Show', GroupHideTool, gid='mygroup')

# Existing tool items can be added repeatedly
# Add an existing tool to new group `foo`.
# It can be added as many times as we want
fig.canvas.manager.toolbar.add_tool('zoom', 'foo')

# Delete tool item
# Remove the forward button
fig.canvas.manager.toolmanager.remove_tool('forward')

# The tool items newly added to the toolbar manager cannot be used directly. They need to be added to the current toolbar through the toolbar object
# If you do not add a custom tool item to the toolbar manager and use the toolbar object directly, an error will be reported
# Add the customized tool item Show to the specific location of the built-in navigation group (i.e. the second location in the group)
# To add a custom tool to the toolbar at specific location inside
# the navigation group
fig.canvas.manager.toolbar.add_tool('Show', 'navigation', 1)
#fig.canvas.manager.toolbar.add_tool('List', 'navigation', 2)
plt.show()

Official case operation results

After running, the customized Show button is in the effective state, and all three lines are displayed.

Click the Show button to handle the failure status, and the two lines of mygroup group will no longer be displayed.

Because the List tool item is only added to the toolbar manager in the case, but not to the toolbar, the List tool item is not displayed in the toolbar. However, the shortcut key m of the List tool item is effective. Press the shortcut key m on the interface and the console will output the following information.

________________________________________________________________________________
Name (id)    Tool description                              Keymap
--------------------------------------------------------------------------------
List         List Tools                                    m
Show         Show by gid                                   G
allnav       Enable all axes toolmanager                   a
back         Back to previous view                         MouseButton.BACK, backspace, c, left
copy         Copy the canvas figure to clipboard           cmd+c, ctrl+c
fullscreen   Toggle fullscreen mode                        ctrl+f, f
grid         Toggle major grids                            g
grid_minor   Toggle major and minor grids
help         Print tool list, shortcuts and description    f1
home         Reset original view                           h, home, r
nav          Enable one axes toolmanager                   1, 2, 3, 4, 5, 6, 7, 8, 9
pan          Pan axes with left mouse, zoom with right     p
quit         Quit the figure                               cmd+w, ctrl+w, q
quit_all     Quit all figures
save         Save the figure                               ctrl+s, s
subplots     Configure subplots
xscale       Toggle scale X axis                           L, k
yscale       Toggle scale Y axis                           l
zoom         Zoom to rectangle                             o
________________________________________________________________________________
Active Toggle tools
Group        Active
--------------------------------------------------------------------------------
default      None
None         {'Show'}

summary

matplotlib supports two kinds of tool items: basic tool items (base class ToolBase) and switching tool items (base class ToolToggleBase).
For basic tool items, you need to pay attention to defining the trigger method, that is, the action when the tool item is triggered.
For switching tool items, attention should be paid to defining the enable and disable methods, that is, the actions in the effective and invalid states. For example, if the method definition involves modifying the image, attention should be paid to redrawing the image.
Pay attention to the process of adding custom tool items! First add the customized tool item to the toolbar manager, and then add it to the current toolbar! The reason why built-in tool items are not added to the toolbar manager is that they have already been added to the toolbar manager!

Turn:

Analysis of matplotlib toolbar source code III (adding and deleting custom tool items)

Posted by prkarpi on Thu, 14 Apr 2022 13:36:13 +0930