Adding custom buttons to the NavigationToolbarTkAgg

Bas Jansen

I have Tkinter based application for which I want to add a custom button that allows the user to specify the x-axis and y-axis, after which the matplotlib canvas would show the specified axes range.

I have been going through other repo's, questions on SO and blog posts, trying to see how to do this which has gotten me to the point where I can add my custom button, it is able to 'zoom' in on the region of interest (fixed to [15,45] for the test) but it forgets it's initial axes (meaning that the default home and back button can't return to anything before the custom plot_axes button was pressed).

The code that I have for my custom toolbar:

# Custom toolbar
class CustomToolbar(NavigationToolbar2TkAgg):
    def plot_axes(self):
        # This function currently makes it so that the 'original view' is lost
        # TODO Fix the above bug
        self.canvas.figure.axes[0].set_xlim([10,60])
        self.canvas.draw()

    def __init__(self,canvas_,parent_):
        self.toolitems = (
            ('Home', 'Reset original view', 'home', 'home'),
            ('Back', 'Back to previous view', 'back', 'back'),
            ('Forward', 'Forward to next view', 'forward', 'forward'),
            ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
            ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
            # TODO Get this poor thing a nice gif
            ('Axes', 'Zoom in on region of interest (15-45)', 'subplots', 'plot_axes'),
            ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
            ('Save', 'Save the figure', 'filesave', 'save_figure'),
            )
        NavigationToolbar2TkAgg.__init__(self,canvas_,parent_)

So the question would be, how should I change the xlim and ylim values in such a way that the GUI doesn't forget the initial xlim/ylim, ensuring that the home and back buttons still work as intended.

MCVE:

#! /usr/bin/env python

# General imports
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from Tkinter import *
import matplotlib
import random

Xdata = xrange(0,60)
Ydata = random.sample(range(1,100),60)

# Custom toolbar
class CustomToolbar(NavigationToolbar2TkAgg):
    def plot_axes(self):
        # This function currently makes it so that the 'original view' is lost
        # TODO Fix the above bug
        self.canvas.figure.axes[0].set_xlim([15,45])
        self.canvas.draw()

    def __init__(self,canvas_,parent_):
        self.toolitems = (
            ('Home', 'Reset original view', 'home', 'home'),
            ('Back', 'Back to previous view', 'back', 'back'),
            # TODO Get this poor thing a nice gif
            ('Axes', 'Zoom in on region of interest (10-60)', 'subplots', 'plot_axes'),
            )
        NavigationToolbar2TkAgg.__init__(self,canvas_,parent_)

# Functions
def openFile(fig,canvas):
    fig.clear()
    axes = fig.add_subplot(111)
    line, = axes.plot(Xdata,Ydata,label="dummy")
    handles, labels = axes.get_legend_handles_labels()
    fig.legend(handles,labels)
    axes.get_xaxis().get_major_formatter().set_useOffset(False)
    axes.set_xlabel("X")
    axes.set_ylabel("Y")
    canvas.draw()   

# Applicatiom
class App():
    def __init__(self, master):
        # CANVAS
        self.fig = matplotlib.figure.Figure()
        self.canvas = FigureCanvasTkAgg(self.fig, master=master)
        self.toolbar = CustomToolbar(self.canvas, master)
        self.canvas.get_tk_widget().pack(fill=BOTH, expand=YES)
        self.canvas.draw()

        # FRAME
        frame = Frame(master)

        # QUIT
        def close():
            root.destroy()
            root.quit()
        root.protocol("WM_DELETE_WINDOW", lambda: close())

        # MENU
        menu = Menu(master)
        master.config(menu=menu)

        filemenu = Menu(menu, tearoff=0)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Open Chromatogram", command=lambda: openFile(self.fig, self.canvas))

# Call the main app
if __name__ == "__main__":
    root = Tk()
    app = App(root)
    root.mainloop()

Additional information:

OS: Win7 Py: 2.7.13 (Anaconda 4.3.0) Libs: Matplotlib 2.0.0

ImportanceOfBeingErnest

It seems to me that you only have to store the current view before changing the limits. I.e. adding self.push_current() might be enough.

class CustomToolbar(NavigationToolbar2TkAgg):
    def plot_axes(self):
        self.push_current()   # <--- add this
        self.canvas.figure.axes[0].set_xlim([15,45])
        self.canvas.draw()

Note: In newer versions of matplotlib you should use NavigationToolbar2Tk instead of NavigationToolbar2TkAgg

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

TOP Ranking

  1. 1

    Failed to listen on localhost:8000 (reason: Cannot assign requested address)

  2. 2

    How to import an asset in swift using Bundle.main.path() in a react-native native module

  3. 3

    Loopback Error: connect ECONNREFUSED 127.0.0.1:3306 (MAMP)

  4. 4

    pump.io port in URL

  5. 5

    Spring Boot JPA PostgreSQL Web App - Internal Authentication Error

  6. 6

    BigQuery - concatenate ignoring NULL

  7. 7

    ngClass error (Can't bind ngClass since it isn't a known property of div) in Angular 11.0.3

  8. 8

    Do Idle Snowflake Connections Use Cloud Services Credits?

  9. 9

    maven-jaxb2-plugin cannot generate classes due to two declarations cause a collision in ObjectFactory class

  10. 10

    Compiler error CS0246 (type or namespace not found) on using Ninject in ASP.NET vNext

  11. 11

    Can't pre-populate phone number and message body in SMS link on iPhones when SMS app is not running in the background

  12. 12

    Generate random UUIDv4 with Elm

  13. 13

    Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

  14. 14

    Is it possible to Redo commits removed by GitHub Desktop's Undo on a Mac?

  15. 15

    flutter: dropdown item programmatically unselect problem

  16. 16

    Change dd-mm-yyyy date format of dataframe date column to yyyy-mm-dd

  17. 17

    EXCEL: Find sum of values in one column with criteria from other column

  18. 18

    Pandas - check if dataframe has negative value in any column

  19. 19

    How to use merge windows unallocated space into Ubuntu using GParted?

  20. 20

    Make a B+ Tree concurrent thread safe

  21. 21

    ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

HotTag

Archive