IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Déporter la toolbar de matplotlib dans une autre frame


Sujet :

Tkinter Python

  1. #1
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 661
    Par défaut Déporter la toolbar de matplotlib dans une autre frame
    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

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 683
    Par défaut
    Citation Envoyé par Julien N Voir le message
    Qu'est-ce qu'il me manque pour que la toolbar puisse manipuler la figure ?
    Vous êtes parti à écrire une tonne de code qui noie le détail de ce que vous voulez réaliser.
    Vous pourriez déjà simplifier comme par exemple:
    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
    import tkinter as tk
     
    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
     
    root = tk.Tk()
    fig, ax = plt.subplots()
     
    t = np.arange(0, 3, .01)
    line, = ax.plot(t, 2 * np.sin(2 * np.pi * t))
     
    canvas = FigureCanvasTkAgg(fig, root)
    canvas.draw()
    canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
    tk.Frame(root, width=100, height=10, bg='blue').pack()
    frame = tk.Frame(root, bg='red') 
    toolbar = NavigationToolbar2Tk(canvas, frame, pack_toolbar=False)
    toolbar.update()
    toolbar.pack(side=tk.BOTTOM, fill=tk.X)
    frame.pack()
    root.mainloop()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 661
    Par défaut
    Merci Wiztricks.

    C'est juste, j'aurais encore pu simplifier plus. Mis à par canvas.draw() et toolbar.update(), ne voyant pas ce qui change avec ce que j'avais écris, et après quelques essais infructueux, j'ai tenté de changer mon graph 3d par le plot proposé dans votre exemple. Avec succès. Donc, au final il semblerait que le vrai problème soit du côté du graph 3d. Si je remplace les lignes du tracé dans votre exemple par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from mpl_toolkits.mplot3d import Axes3D
     
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    La manipulation de la figure ne fonctionne pas chez moi. Je dois donc chercher le problème ailleurs.

    Merci encore.

    Julien

  4. #4
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 661
    Par défaut
    Maintenant que je sais quoi chercher, j'ai la réponse :

    https://stackoverflow.com/questions/...ot-pan-or-zoom

    Il faut créer le canvas avant l'axe de la figure. En reprenant le code de Wiztricks :
    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
    import tkinter as tk
     
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
     
    root = tk.Tk()
    fig = plt.figure()
     
    canvas = FigureCanvasTkAgg(fig, root)
    canvas.draw()
    canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
     
    ax = fig.gca(projection='3d')
    t = np.arange(0, 3, .01)
    line, = ax.plot(t, 2 * np.sin(2 * np.pi * t))
     
    tk.Frame(root, width=100, height=10, bg='blue').pack()
    frame = tk.Frame(root, bg='red') 
    toolbar = NavigationToolbar2Tk(canvas, frame)
    toolbar.update()
    toolbar.pack(side=tk.BOTTOM, fill=tk.X)
    frame.pack()
    root.mainloop()
    Julien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 15/02/2007, 00h24
  2. Réponses: 7
    Dernier message: 18/01/2007, 15h03
  3. Lien dans une autre frame SVP
    Par kaisersauze dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 29/05/2006, 00h53
  4. Modifier un texte dans une autre frame
    Par hotkebab99 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/02/2006, 14h46
  5. Passage d'infos dans une autre frame
    Par dumser1 dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 23/11/2005, 09h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo