Bonjour,

Je cherche à déporter la toolbar de Matplotlib dans une autre frame que celle où s'affiche la figure. J'arrive sans problème à afficher la toolbar, mais j'ai un soucis de compréhension sur la façon de procéder pour conserver la barre fonctionnelle. Je n'ai aucun message d'erreur. Seulement, aucun bouton ne semble fonctionner. Je suppose qu'il s'agit d'un problème de référence pour la gestion des événements.

J'utilise une assez vielle version de matplotlib, la 2.2.2 (je n'ai pas le choix de la version).

Ci-dessous un proto qui reproduit mon problème :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# GUI modules
import tkinter as tk
import tkinter.ttk as ttk
 
# Plotting modules
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk
 
 
class GraphArea(tk.PanedWindow):
 
    _width = 860
    _height = 650
 
    def __init__(self, parent, *args, **kwargs):
        tk.PanedWindow.__init__(self, parent, *args, **kwargs)
        self.grid()
        self.initialize()
 
    def initialize(self):
 
        # Build figure 
        self.fig = plt.figure()
        self.ax = self.fig.gca(projection='3d')
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
 
        # Pack the canvas into a widget
        figure_widget = self.canvas.get_tk_widget()
        figure_widget.config(height=self._height, width=self._width)
        figure_widget.pack()
 
 
class ButtonGraphArea(tk.PanedWindow):
 
    def __init__(self, parent, child, *args, **kwargs):
        """Initialization method.
 
        Parameters
        ----------
        parent : tk frame
            Master frame.
        child : tk frame
            Dependant graph area
        """
        tk.PanedWindow.__init__(self, parent, *args, **kwargs)
        self.graph_area = child
        self.grid()  
        self.initialize()
 
    def initialize(self):
 
        canvas = self.graph_area.canvas
        mpl_toolbar = NavigationToolbar2Tk(canvas, self)
        mpl_toolbar.pack()
 
 
class MainApplication(tk.Frame):
 
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.master = parent
        self.grid(sticky='NSEW')
        self.initialize()
 
    def initialize(self):
 
        self.graph_area = GraphArea(self)
        self.graph_area.grid(row=0, column=0, sticky='NSEW')
 
        separator = ttk.Separator(self, orient=tk.HORIZONTAL)
        separator.grid(row=1, column=0, sticky='EW')
 
        self.button_graph_area = ButtonGraphArea(self, self.graph_area)
        self.button_graph_area.grid(row=2, column=0, sticky='NSEW')
 
 
if __name__ == '__main__':
 
    # pour illustrer que la toolbar fonctionne pour le cas usuel
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    plt.show()
 
    root = tk.Tk()
    app = MainApplication(root)
    root.mainloop()
J'ai deux frames, l'une qui contient la figure, l'autre qui contient entre autres choses la toolbar. La frame qui contient la toolbar possède en attribut la frame de la figure, et donc la figure elle-même et son canvas.

Qu'est-ce qu'il me manque pour que la toolbar puisse manipuler la figure ?

Julien