1

I am trying to get tkinter check button implemented with matplotlib in order to update the plot and show the selected plots only.

However, the check button wouldn't change the variable.

I've tried different versions of python and stripping down most of my code to just simple tkinter and matplotlib integration, without any luck.

# coding: utf-8
# usr/bin/python37

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from tkinter import messagebox, Button, Tk, BooleanVar
from tkinter.ttk import Checkbutton
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')


class GUI:
    fig = plt.figure()
    sub = fig.add_subplot(1, 1, 1)

    def __init__(self, root):
        self.root = root
        self.root.title("Testing")
        self.setupTk()

    def setupTk(self):
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
        self.canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
        self.canvas._tkcanvas.pack(side='top', fill='both', expand=1)
        '''
        Problem
        '''
        self.var = BooleanVar()
        self.var.set(True)
        self.button = Checkbutton(
            self.root, variable=self.var, text='Direvative', command=self.cb)
        self.button.pack(side='left')
        '''
        /Problem
        '''
        self.button = Button(master=self.root, text='Quit', command=self._quit)
        self.button.pack(side='right')

        self.toolbar = NavigationToolbar2Tk(self.canvas, self.root)
        self.toolbar.update()

        self.root.protocol("WM_DELETE_WINDOW", self._quit)

    def cb(self):
        print(self.var.get())

    def _quit(self):
        if messagebox.askquestion('Exit Application', 'Are you sure you want to exit the application', icon='warning') == 'yes':
            self.root.quit()
            self.root.destroy()


if __name__ == '__main__':
    root = Tk()
    mod = GUI(root)
    root.mainloop()

I am using: Python: 3.7.3 Matplotlib: 3.1.1

I expect the printout to change as the user clicks the check button.

Please feel free to point me towards resources online.

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
Abrian Abir
  • 77
  • 10

1 Answers1

2

You need to use matplotlib.Figure instead of pyplot.figure.
You also had two buttons with the same name, but that was not the problem.

The following code embeds a matplotlib.Figure, with a subplot and a toolbar, in a tkinter.window that has a check_button, and a quit_button. I removed the messagebox that I found irritating, but you can put it back, there was nothing wrong with the code.

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from tkinter import messagebox, Button, Tk, BooleanVar
from tkinter.ttk import Checkbutton
from matplotlib.figure import Figure
import matplotlib
matplotlib.use('TkAgg')


class GUI:

    fig = Figure()
    sub = fig.add_subplot(1, 1, 1)

    def __init__(self, root):
        self.root = root
        self.root.title("Testing")
        self.setupTk()

    def setupTk(self):

        self.var = BooleanVar()
        self.var.set(True)
        self.check_button = Checkbutton(
            self.root, variable=self.var, text='Direvative', command=self.cb)
        self.check_button.pack(side='left')

        self.quit_button = Button(master=self.root, text='Quit', command=self._quit)
        self.quit_button.pack(side='right')

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
        self.canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
        self.canvas._tkcanvas.pack(side='top', fill='both', expand=1)

        self.toolbar = NavigationToolbar2Tk(self.canvas, self.root)
        self.toolbar.update()

        self.root.protocol("WM_DELETE_WINDOW", self._quit)

    def cb(self):
        print(self.var.get())

    def _quit(self):
        self.root.destroy()


if __name__ == '__main__':
    root = Tk()
    mod = GUI(root)
    root.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • 1
    You're missing the matplotlib import but it works, Thanks! – Abrian Abir Jul 15 '19 at 02:13
  • You are welcome. Ah yes, the quirks of using jupyter notebook where there is persistence of imports and variables - sorry about that. I edited the code. – Reblochon Masque Jul 15 '19 at 02:16
  • 1
    Had always wondered why `Figure` is recommended over `plt.figure`. +1 for showcasing it :) – Henry Yik Jul 15 '19 at 02:54
  • Yes @HenryYik, thank you, the short answer is given [here](https://stackoverflow.com/a/43483054/2875563) - the longer one [there](https://matplotlib.org/faq/usage_faq.html) – Reblochon Masque Jul 15 '19 at 03:12
  • 1
    @HenryYik There is nothing wrong with `plt.figure()` in general. The key here is that the figure is to be *embedded* into tkinter. In such cases, you do not want to have your figure managed by pyplot, because you want to manage it yourself through the GUI toolkit you're using. – ImportanceOfBeingErnest Jul 15 '19 at 08:20