我有基于Tkinter的应用程序,我想添加一个自定义按钮,允许用户指定x轴和y轴,之后matplotlib画布将显示指定的轴范围。
我一直在浏览其他repo's,SO和博客posts上的问题,试图了解如何做到这一点,这让我能够添加自定义按钮,它可以“放大”感兴趣的区域(测试时固定为[15,45]),但它会忘记它的初始轴(意味着默认的home
和back
按钮在按下自定义plot_axes
按钮之前无法返回任何内容。
我的自定义工具栏代码:
# 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_)
所以问题是,如何更改xlim和ylim值,使GUI不会忘记初始xlim / ylim,确保home
和back
按钮仍然按预期工作。
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()
其他信息:
操作系统:Win7 Py:2.7.13(Anaconda 4.3.0) Libs:Matplotlib 2.0.0
答案 0 :(得分:3)
在我看来,您只需在更改限制之前存储当前视图。即添加self.push_current()
可能就足够了。
class CustomToolbar(NavigationToolbar2TkAgg):
def plot_axes(self):
self.push_current() # <--- add this
self.canvas.figure.axes[0].set_xlim([15,45])
self.canvas.draw()
注意:在较新版本的matplotlib中,您应使用NavigationToolbar2Tk
代替NavigationToolbar2TkAgg