简体   繁体   中英

How to get buttons on a matplotlib subplot in Tkinter?

I am a newbie to Tkinter and would like to get buttons inside the matplotlib subplot and display it using Tkinter. I did search the internet but couldn't get anything to quite fit my needs. If anybody could provide any insights, would be really greatful!

As of now, I tried something like this (See code below) and got the matplotlib figure in a figure canvas. I would like to know how to enable two buttons inside each subplot.

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
import numpy as np
from tkinter import *
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure 
from PIL import Image

win = Tk()

folder = r'D:\V\Bilder_resized\Test'
im = np.arange(100)
im.shape = 10, 10

fig = plt.figure(figsize = (10,10))

grid = ImageGrid(fig, 221,  # similar to subplot(111)
             nrows_ncols=(2, 2),  # creates 2x2 grid of axes
             axes_pad=0.25,  # pad between axes in inch.
             )
for gridax in grid:
    gridax.set_title('True Positive', fontsize = 13)
    gridax.set_xticks([])
    gridax.set_yticks([])
grid_1 = ImageGrid(fig, 222,  # similar to subplot(111)
             nrows_ncols=(1, 2),  # creates 2x2 grid of axes
             axes_pad=0.25,  # pad between axes in inch.
             )
for gridax in grid_1:
    gridax.set_title('False Positive', fontsize = 13)
    gridax.set_xticks([])
    gridax.set_yticks([])
grid_2 = ImageGrid(fig, 223,  # similar to subplot(111)
             nrows_ncols=(1, 2),  # creates 2x2 grid of axes
             axes_pad=0.25,  # pad between axes in inch.
             )
for gridax in grid_2:
    gridax.set_title('False Negative', fontsize = 13)
    gridax.set_xticks([])
    gridax.set_yticks([])
grid_3 = ImageGrid(fig, 224,  # similar to subplot(111)
             nrows_ncols=(2, 2),  # creates 2x2 grid of axes
             axes_pad=0.25,  # pad between axes in inch.
             )
for gridax in grid_3:
    gridax.set_title('True Negative', fontsize = 13)
    gridax.set_xticks([])
    gridax.set_yticks([])

for i in range(4):
    image = os.path.join(folder, true_positive[i])
    img= Image.open(image)
    d = ImageDraw.Draw(img)
    d.text((30,30),"{}".format(np.round(true_positive_confidence[i],2)), 
fill = (255,255,0))
grid[i].imshow(img) 
# The AxesGrid object work as a list of axes.
x = len(false_positive)
c = len(false_negative)

if x < 2:
    a =x 
else:
   a =2

for i in range(a):
    image = os.path.join(folder, false_positive[i])
    img= Image.open(image)
    d = ImageDraw.Draw(img)
    d.text((30,30),"{}".format(np.round(false_positive_confidence[i],2)), 
fill = (255,255,0))
    grid_1[i].imshow(img)
if c < 2:
    b = c
else:
    b =2    
for i in range(b):
    image = os.path.join(folder, false_negative[i])
    img= Image.open(image)
    d = ImageDraw.Draw(img)
    d.text((30,30),"{}".format(np.round(false_negative_confidence[i],2)), 
fill = (255,255,0))
    grid_2[i].imshow(img)
for i in range(4):
    image = os.path.join(folder, true_negative[i])
    img= Image.open(image)
   d = ImageDraw.Draw(img)
d.text((30,30),"{}".format(np.round(true_negative_confidence[i],2)), fill = (255,255,0))
grid_3[i].imshow(img)

canvas = FigureCanvasTkAgg(fig, master=win)

graph_widget = canvas.get_tk_widget()
graph_widget.grid(row=0, column=0, columnspan=3, sticky = 'nsew')
win.mainloop()
plt.show()

The output of the code: output of the above code

I would like to embed "Previous" and "Next" buttons below each of the subplots to navigate inside the folder to display the previous or the next set of images. I am also adding an example image on how I need it. Example image

If anybody could provide any ideas on how to do it, would be really helpful. Sorry if something is not clear in my post!

A better way to organize will be creating a Frame to hold each of your Figure object and the buttons, and then grid your frames. Below is a sample using a class inherited from tk.Frame :

import numpy as np
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

win = tk.Tk()

class FigureFrame(tk.Frame):
    def __init__(self,master=None,**kwargs):
        super().__init__(master,**kwargs)
        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        graph_widget = self.canvas.get_tk_widget()
        graph_widget.grid(row=0, column=0, columnspan=3, sticky = 'nsew')
        self.plot_next()
        tk.Button(self,text="Prev",command=self.plot_next).grid(row=1,column=0,sticky="w")
        tk.Button(self,text="Next",command=self.plot_next).grid(row=1,column=2,sticky="e")

    def plot_next(self):
        self.fig.clear()
        r = np.random.randint(1,10,5)
        self.fig.add_subplot(111).plot(r)
        self.canvas.draw_idle()

for i in range(4):
    f = FigureFrame(win)
    f.grid(row=i//2,column=i%2)

win.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM