Matplotlib/Tkinter - customizing toolbar tooltips

后端 未结 1 2074
名媛妹妹
名媛妹妹 2020-12-10 09:24

I created an application based on Tkinter that uses Matplotlib for plotting a waveform. I wonder how I could change the tooltips for the Matplotlib toolbar buttons (I need t

相关标签:
1条回答
  • 2020-12-10 09:53

    PART 1

    So this should be pretty straight forward. The NavigationToolbar2TkAgg class inherits from NavigationToolbar2 which can be found in matplotlib.backend_bases. If you look at NavigationToolbar2TkAgg, you will see that the pop-up text for the buttons is stored in an attribute called self.toolitems. This attribute is inherited from the base class, where it is defined as:

    # list of toolitems to add to the toolbar, format is:                                                                             
    # (                                                                                                                               
    #   text, # the text of the button (often not visible to users)                                                                   
    #   tooltip_text, # the tooltip shown on hover (where possible)                                                                   
    #   image_file, # name of the image for the button (without the extension)                                                        
    #   name_of_method, # name of the method in NavigationToolbar2 to call                                                            
    # )                                                                                                                               
    toolitems = (
        ('Home', 'Reset original view', 'home', 'home'),
        ('Back', 'Back to  previous view', 'back', 'back'),
        ('Forward', 'Forward to next view', 'forward', 'forward'),
        (None, None, None, None),
        ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
        ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
        (None, None, None, None),
        ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
        ('Save', 'Save the figure', 'filesave', 'save_figure'),
        )
    

    The second item in each tuple is the text that is pops up when you mouse-over the button. To override this, just subclass and make your own version of toolitems.

    For example (with filler text):

    import numpy as np
    import Tkinter as tk
    import matplotlib as mpl
    from matplotlib.patches import Rectangle
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
    
    # custom toolbar with lorem ipsum text
    class CustomToolbar(NavigationToolbar2TkAgg):
        def __init__(self,canvas_,parent_):
            self.toolitems = (
                ('Home', 'Lorem ipsum dolor sit amet', 'home', 'home'),
                ('Back', 'consectetuer adipiscing elit', 'back', 'back'),
                ('Forward', 'sed diam nonummy nibh euismod', 'forward', 'forward'),
                (None, None, None, None),
                ('Pan', 'tincidunt ut laoreet', 'move', 'pan'),
                ('Zoom', 'dolore magna aliquam', 'zoom_to_rect', 'zoom'),
                (None, None, None, None),
                ('Subplots', 'putamus parum claram', 'subplots', 'configure_subplots'),
                ('Save', 'sollemnes in futurum', 'filesave', 'save_figure'),
                )
            NavigationToolbar2TkAgg.__init__(self,canvas_,parent_)
    
    
    class MyApp(object):
        def __init__(self,root):
            self.root = root
            self._init_app()
    
        # here we embed the a figure in the Tk GUI
        def _init_app(self):
            self.figure = mpl.figure.Figure()
            self.ax = self.figure.add_subplot(111)
            self.canvas = FigureCanvasTkAgg(self.figure,self.root)
            self.toolbar = CustomToolbar(self.canvas,self.root)
            self.toolbar.update()
            self.plot_widget = self.canvas.get_tk_widget()
            self.plot_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
            self.toolbar.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
            self.canvas.show()
    
        # plot something random
        def plot(self):
            self.ax.imshow(np.random.normal(0.,1.,size=[100,100]),cmap="hot",aspect="auto")
            self.figure.canvas.draw()
    
    def main():
        root = tk.Tk()
        app = MyApp(root)
        app.plot()
        root.mainloop()
    
    if __name__ == "__main__":
        main()
    

    This should give you a normal embedded matplotlib figure, but when you mouse-over the buttons you will get something like:

    Custom toolbar text example

    PART 2

    The second part of the question is less elegant. The text for "pan/zoom" and "zoom rect" is hardcoded into the pan and zoom methods of the toolbar. The actual text is held in the self.mode attribute of the toolbar. The easiest way to overwrite what this produces is to make subclass wrappers for the baseclass pan and zoom methods.

    These wrappers go in the CustomToolbar class from above like:

    def pan(self):
        NavigationToolbar2TkAgg.pan(self)
        self.mode = "I'm panning!" #<--- whatever you want to replace "pan/zoom" goes here
        self.set_message(self.mode)
    
    def zoom(self):
        NavigationToolbar2TkAgg.zoom(self)
        self.mode = "I'm zooming!" #<--- whatever you want to replace "zoom rect" goes here
        self.set_message(self.mode)
    

    This is just one way to do this, another might be to wrap the set_message method to catch and translate specific bits of text.

    0 讨论(0)
提交回复
热议问题