[Python] Extension using inheritance of matplotlib (NavigationToolbar2TK)

Personal memorandum.

Issue setting

--In the next product, we aim to be able to analyze data using matplotlib plots, but since it is a little inflexible, we would like to add a GUI so that Tkinter can operate graphs freely.

--Therefore, we will extend NavigationToolbar2TK, which is the default navigation toolbar.

Collection of examples

Hide some buttons displayed in the Navigation Toolbar

Source code

disable_somebuttons.py



import matplotlib.pyplot as plt
import tkinter as tk

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)

class NavigationToolbarExt(NavigationToolbar2Tk):
    toolitems = [t for t in NavigationToolbar2Tk.toolitems if t[0] in ('Pan', 'Save')]

## ---abridgement--- ##
##Below is the main program###

root = tk.Tk()
fig = plt.figure(figsize=(8, 5))

canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()

toolbar = NavigationToolbarExt(canvas, root)

canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
toolbar.pack(side=tk.BOTTOM, fill=tk.BOTH)

root.protocol("WM_DELETE_WINDOW", toolbar.quit)
root.mainloop()

Execution result

image.png

Only Pan and Save will be displayed.

Add a new button to the Navigation Toolbar using a custom icon

--Add a declaration statement related to self._buttons to the constructor.

――In addition, ToolTip will not work with this alone, so I will add a sentence about ToolTip.

--Currently, toggle = False, but there is a possibility that toggle = True can be supported by overriding another method. (Investigation required)

originalbutton.py



import matplotlib.pyplot as plt
import tkinter as tk

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backends._backend_tk import (ToolTip)

class NavigationToolbarExt(NavigationToolbar2Tk):
    toolitems = [t for t in NavigationToolbar2Tk.toolitems if t[0] in ('Pan', 'Save')]

    def __init__(self, canvas=None, master=None):
        super().__init__(canvas, master)

        # move2.With png as an icon, when that button is clicked, a member method called HelloWorld is executed.
        #In addition, Foo as ToolTip?Is displayed.
        self._buttons["Foo"] = (self._Button('Foo', 'move2.png', toggle=False , command=getattr(self, 'HelloWorld'))) 
        ToolTip.createToolTip(self._buttons["Foo"], 'Foo?')
        self.canvas = canvas
        self.master = master

    def HelloWorld(self):
        print("HelloWorld")

### (Omitted below) ###

In subplot, change the process so that only some graphs (here, subplot 1st) can be panned.

--Override press_pan

pan_somegraph.py



import matplotlib.pyplot as plt
import tkinter as tk

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)

class NavigationToolbarExt(NavigationToolbar2Tk):
    def press_pan(self, event):
        if( event.inaxes != None):  #When clicked outside the frame(event.inaxes==None)Want to ignore
            if event.inaxes.get_subplotspec().colspan.start == 1:   #Only the one specified as No. 1 is targeted
                super().press_pan(event)

### (Omitted below) ###

Don't accept click events while panning

--Override pan

--In C #, the delegate operator (+ =,-=) is often used to control whether or not an event can be accepted, but it was implemented using the same principle. The corresponding functions are mpl_connect and mpl_disconnect.

Note that if you don't put a button event in the constructor as well, the click of the first action will be ignored. The constructor is also light but needs to be implemented.

pan_click_available_onlyidle.py



import matplotlib.pyplot as plt
import tkinter as tk

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import (_Mode)

class NavigationToolbarExt(NavigationToolbar2Tk):
    toolitems = [t for t in NavigationToolbar2Tk.toolitems if t[0] in ('Pan', 'Save')]

    def __init__(self, canvas=None, master=None):
        super().__init__(canvas, master)
        self.canvas = canvas
        self.master = master

        self.pressevent_cid = fig.canvas.mpl_connect('button_press_event', self.onclick)  #Need here

    def pan(self):
        super().pan()
        if self.mode == _Mode.PAN:  #When in PAN mode
            fig.canvas.mpl_disconnect(self.pressevent_cid)    #Delete event
        else:  #If not in PAN mode
            self.pressevent_cid = fig.canvas.mpl_connect('button_press_event', self.onclick)  #Add an event

    def onclick(self, event):
        print("Clicked")

## (Omitted below) ###

Change the background color of the Navigation Toolbar

When I made a pull request, I received another proposal. This may be the cleanest form. However, there are some concerns when setting a color other than the background color.


import matplotlib.pyplot as plt
import tkinter as tk

from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)

class NavigationToolbarExt(NavigationToolbar2Tk):
    def __init__(self, canvas=None, master=None):
        super().__init__(canvas, master)   
        self.canvas = canvas
        self.master = master

        self['bg'] = 'white'
        for item in self.winfo_children():
           item['bg'] = 'white'

Accept end event

Since tkinter is used, python.exe may not end unless the following syntax is added to the main routine, so be careful.

root.protocol("WM_DELETE_WINDOW", toolbar.quit)

Recommended Posts

[Python] Extension using inheritance of matplotlib (NavigationToolbar2TK)
Installation of matplotlib (Python 3.3.2)
python: Basics of using scikit-learn ①
Image capture of firefox using python
Installation of SciPy and matplotlib (Python)
[Python of Hikari-] Chapter 09-03 Class (inheritance)
Removal of haze using Python detailEnhanceFilter
Installation of Python, SciPy, matplotlib (Windows)
Implementation of desktop notifications using Python
Python #inheritance (inheritance)
Python: Basics of image recognition using CNN
Automatic collection of stock prices using python
About building GUI using TKinter of Python
(Bad) practice of using this in Python
Flexible animation creation using animation.FuncAnimation of matplotlib
Python: Application of image recognition using CNN
External display of matplotlib diagrams using tkinter
Study on Tokyo Rent Using Python (3-1 of 3)
[Python] Japanese localization of matplotlib on Ubuntu
Meaning of using DI framework in Python
Time variation analysis of black holes using python
Introduction of Python
Build Python3.5 + matplotlib environment on Ubuntu 12 using Anaconda
[Python] limit axis of 3D graph with Matplotlib
Chord recognition using chromagram of python library librosa
#Python basics (#matplotlib)
Start using Python
Introduction of Python Imaging Library (PIL) using HomeBrew
About python inheritance
Character encoding when using csv module of python 2.7.3
Basics of Python ①
Basics of python ①
Copy of python
My matplotlib (python)
Try using the collections module (ChainMap) of python3
Anonymous upload of images using Imgur API (using Python)
Code for checking the operation of Python Matplotlib
Find the geometric mean of n! Using Python
Try using matplotlib
Python introductory study-output of sales data using tuples-
Scraping using Python
Basic story of inheritance in Python (for beginners)
Introduction of Python
Summary of Excel operations using OpenPyXL in Python
[Python] Implementation of clustering using a mixed Gaussian model
Explanation of the concept of regression analysis using python Part 2
Basics of I / O screen using tkinter in python3
I tried to summarize how to use matplotlib of python
[Python] [Word] [python-docx] Simple analysis of diff data using python
[Python] I immediately tried using Pylance's VS Code extension.
Cut a part of the string using a Python slice
Try projective transformation of images using OpenCV with Python
Derivatives Learned Using Python-(1) Calculation of Forward Exchange Rate-
[Question] About API conversion of chat bot using Python
The pain of gRPC using Python. November 2019. (Personal memo)
[Python] Using Line API [1st Creation of Beauty Bot]
Explanation of the concept of regression analysis using Python Part 1
[Python] Summary of table creation method using DataFrame (pandas)
Explanation of the concept of regression analysis using Python Extra 1
Study from the beginning of Python Hour8: Using packages
[Introduction to Python] Basic usage of the library matplotlib