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
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.
Comments