matplotlib 在 tkinter 画布中的缩放功能

Posted

技术标签:

【中文标题】matplotlib 在 tkinter 画布中的缩放功能【英文标题】:matplotlib's zoom functionality inside a tkinter canvas 【发布时间】:2014-05-10 19:57:53 【问题描述】:

我一直在尝试在 GUI 后面传输一些脚本(使用 Tkinter),到目前为止,所有打开的数据都显示在 Tkinter 画布中(使用 matplotlib 绘制)。

我遇到的唯一问题是 matplotlib 中的标准缩放/滚动(使用鼠标左键“移动”绘图和鼠标右键“缩放”)基本上无法在画布中访问matplotlib 绘图窗口中“4 点十字”的功能。

我认为这需要创建我自己的处理程序,但我认为必须有一种方法来使用 matplotlib 的默认处理程序?我还查看了this 问题中提到的“滚动”画布选项,但那些似乎只是改变绘图区域的大小而不是放大/缩小数据,我也不想添加任何进一步的按钮操纵情节区域。

我目前拥有的最低限度代码:

#! /usr/bin/env python
from Tkinter import *
import matplotlib.pyplot as plt
import matplotlib.backends.backend_tkagg as tkagg
import tkFileDialog

class App():
    def __init__(self,master):
        # VARIABLES
        self.inputFile = ""
        self.fig = plt.Figure()
        self.canvas = tkagg.FigureCanvasTkAgg(self.fig, master = master)
        self.canvas.get_tk_widget().pack()
        self.canvas.draw()

        # FRAME
        frame = Frame(master)
        master.title("MassyTools 0.1.1 (Alpha)")

        # VARIABLE ENTRIES

        # BUTTONS

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

        filemenu = Menu(menu)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Open Input File", command = self.openFile)
        calibmenu = Menu(menu)
        menu.add_cascade(label="Calibrate",menu=calibmenu)
        calibmenu.add_command(label="Open Calibration File", command = self.openCalibrationFile)
        calibmenu.add_command(label="Calibrate", command = self.calibrateData)  

    def openFile(self):
        file_path = tkFileDialog.askopenfilename()
        setattr(self,'inputFile',file_path)
        data = self.readData()
        self.plotData(data)

    def openCalibrationFile(self):
        print "Place holder for selection of the calibration file"

    def calibrateData(self):
        print "Place holder for actual calibration"

    def readData(self):
        x_array = []
        y_array = []
        with open(self.inputFile,'r') as fr:
            for line in fr:
                line = line.rstrip('\n')
                values = line.split()
                x_array.append(float(values[0]))
                y_array.append(float(values[1]))
        return zip(x_array,y_array)

    def plotData(self,data):
        x_array = []
        y_array = []
        for i in data:
            x_array.append(i[0])
            y_array.append(i[1])
        self.fig.clear()
        self.axes = self.fig.add_subplot(111)
        self.line, = self.axes.plot(x_array,y_array)
        self.canvas.draw()

# Stuff that is not being used now but can be useful                        
    """def openFile(self,number):
        name = tkFileDialog.askopenfilename()
        ops = 
            1: 'deglycoData',
            2: 'peptideFile',
            3: 'mzML'
        
        setattr(self,ops[number],name)
    """
# End of 'stuff'

root = Tk()
app = App(root)
root.mainloop()

【问题讨论】:

【参考方案1】:

因此,您可以将NavigationToolbar2TkAgg 对象附加到您的画布上,这将为您提供所有正常的 matplotlib 方法和工具。

import matplotlib.backends.backend_tkagg as tkagg

# canvas is your canvas, and root is your parent (Frame, TopLevel, Tk instance etc.)
tkagg.NavigationToolbar2TkAgg(canvas, root)

可以在这里找到一个很好的用法示例:Updating a graphs coordinates in matplotlib。

可以在here(参见class NavSelectToolbar(NavigationToolbar2TkAgg))中找到如何添加自定义方法的示例。

【讨论】:

嗯,这比我预期的要容易。我非常感谢您问题的第二部分,因为它应该可以帮助我在不添加可见按钮的情况下获得功能(希望如此)。 注意子类化NavigationToolbar2TkAgg 有一些隐藏的陷阱。没什么大不了的,但如果你遇到任何有趣的行为,你会想看看源代码。

以上是关于matplotlib 在 tkinter 画布中的缩放功能的主要内容,如果未能解决你的问题,请参考以下文章

Python Tkinter 在 GUI 中嵌入 Matplotlib

将matplotlib嵌入到tkinter画布中会打开两个窗口

对于实时数据,Tkinter matplotlib 画布更新太慢

使用带有 pylab/matplotlib 嵌入的 Tkinter 播放、暂停、停止功能的彩色绘图动画:无法更新图形/画布?

使用 matplotlib 清除 Tkinter Canvas 小部件的问题

Matplotlib NavigationToolbar小部件未显示在Tkinter GUI中