在矩形类缩放中选择区域时出错(wx.frame) [英] error when select area inside rectangle class zoom(wx.frame)

查看:45
本文介绍了在矩形类缩放中选择区域时出错(wx.frame)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在对矩形选择器内的绘图区域有一些帮助后,我工作了,但是当我在某些代码应用程序中应用时,我遇到了如下错误:

after have some help about plot area inside rectangle selector i worked but when i applicated in some code app i have error like :

Traceback (most recent call last):
  File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\cbook\__init__.py", line 215, in process
    func(*args, **kwargs)
  File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\widgets.py", line 1597, in release
    self._release(event)
  File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\widgets.py", line 2194, in _release
    self.onselect(self.eventpress, self.eventrelease)
TypeError: line_select_callback() missing 1 required positional argument: 'erelease'

我不知道为什么它不能在我的应用程序中运行类(缩放)一切都很好,但我不知道代码中的问题在哪里.

i don't know why it can't working the class(zoom) in my app all is good i thing but i dont know where is the problem inside code .

当我需要在矩形内选择区域时,这是第二个应用程序的代码:

this is code for second application when i need to do the select area inside rectangle :

import wx
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
import matplotlib
import matplotlib.pyplot as plt
import os



class MainFrame(wx.Frame):
    def __init__(self, parent ):
        super().__init__(parent,title= "quick",size = (2000,1000))

        left = LeftPanel(self)
        middle = MiddlePanel(self)
        right = RightPanel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(left, 3, wx.EXPAND)
        sizer.Add(middle, 5, wx.EXPAND)
        sizer.Add(right, 5, wx.EXPAND)
        self.SetSizer(sizer)


# ------------ LEFT ------------

class LeftPanelTop(wx.Panel):
    def __init__(self, parent,size = (610,350)):
        super().__init__(parent)
        self.figure = Figure(figsize =(5,3))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.Size = self.canvas.Size
        self.zoom_axes = []




    def load_from_file(self, file_name):
        """
        Méthode effectuant l'intermédiaire pour charger le fichier selon
        son type
        """
        self.axes = self.figure.add_subplot(111)

        if file_name.endswith(".nc"):
            self._load_nc(file_name)
        else:
            self._load_txt(file_name)
        self.canvas.draw()

    def _load_nc(self, file_name):
        """ Simule le chargement et affichage à partir d'un fichier nc """
        t = np.arange(0.0, 8.0, 0.01)
        s = np.sin(3 * np.pi * t)
        self.axes.plot(t, s)


        self.RS = RectangleSelector(self.axes,line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=5, minspany=5,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))


def line_select_callback(self,eclick, erelease):
    x1, y1 = eclick.xdata, eclick.ydata
    x2, y2 = erelease.xdata, erelease.ydata
    self.zoom_axis=[x1,x2,y1,y2]
    Zoom(parent=self)



class Zoom(wx.Frame):
    def __init__(self,parent):
        wx.Frame.__init__(self,parent,-1,("Zoom"))
        self.parent

        #Make this zoom window self cancelling if it loses focus
        self.Bind(wx.EVT_ACTIVATE, self.OnExit)

        #Load axis values of the selected rectangle
        zoom_axis=parent.zoom_axis

        #duplicate the plot from the main panel
        self.figure = Figure(figsize =(5,6))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        """ Simule le chargement et affichage à partir d'un fichier nc """
        t = np.arange(0.0, 8.0, 0.01)
        s = np.sin(3 * np.pi * t)


        #Apply axis of drawn rectangle to the plot
        self.axes.axis(zoom_axis)
        self.axes.pcolormesh(air_dep,cmap=plt.get_cmap('binary'))
        self.canvas.draw()
        self.show()

    def OnExit(self, event):
        focus = event.GetActive()
        if focus == True : # Window lost focus
            self.Close()


class LeftPanelBottom(wx.Panel):
     def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER,size = (510,450) )
        self.SetBackgroundColour('snow2')
        panel_buttons = wx.Panel(self)
        canvas_panel = LeftPanelTop(self)
        panel_buttons_sizer = wx.GridSizer(1, 2, 0, 0)
        select_button = PickButton(
            panel_buttons,
            "netCDF4 files (nc)|*.nc",
            canvas_panel.load_from_file,
            label="Open file",)
        panel_buttons_sizer.Add(select_button)
        panel_buttons.SetSizer(panel_buttons_sizer)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel_buttons)
        sizer.Add(canvas_panel)
        self.SetSizer(sizer)


class PickButton(wx.Button):
    """ Bouton permettant de choisir un fichier """

    def __init__(self, parent, wildcard, func, **kwargs):
        # func est la méthode à laquelle devra être foruni le fichier sélectionné
        super().__init__(parent, **kwargs)
        self.wildcard = wildcard
        self.func = func
        self.Bind(wx.EVT_BUTTON, self.pick_file)

    def pick_file(self, evt):
        style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
        with wx.FileDialog(
            self, "Pick files", wildcard=self.wildcard, style=style
        ) as fileDialog:
            if fileDialog.ShowModal() != wx.ID_CANCEL:
                chosen_file = fileDialog.GetPath()
                self.func(chosen_file)

class LeftPanel(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)

        top = LeftPanelTop(self)
        bottom = LeftPanelBottom(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(top, 3, wx.EXPAND)
        sizer.Add(bottom, 4, wx.EXPAND)

        self.SetSizer(sizer)

# ------------ MIDDLE ------------

class MiddlePanelTop(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)
        self.SetBackgroundColour('black')
        canal=wx.Button(self,-1,label ="Variable",size=(140,30),pos=(100,0))
        dynamique=wx.Button(self,-1,"Dynamique",size=(140,30),pos=(240,0))
        file = wx.Button(self,-1,"File", size = (110,30),pos=(0,0))
        dynamique.SetBackgroundColour('white')

        canal.SetBackgroundColour('white')
        file.SetBackgroundColour('white')
        dynamique.Bind(wx.EVT_BUTTON, self.OnClick)
        file.Bind(wx.EVT_BUTTON, self.onOpen)

    def onOpen(self, event):
        wildcard = "netCDF4 files (*.nc)|*.nc"
        dialog = wx.FileDialog(self, "Open netCDF4 Files", wildcard=wildcard,
                               style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if dialog.ShowModal() == wx.ID_CANCEL:
            return


        path = dialog.GetPath()

        if os.path.exists(path):
            with open(path) as fobj:
                for line in fobj:
                    self.my_text.WriteText(line)

    def OnClick(self,event):
        dlg = wx.TextEntryDialog(self, 'Enter Dynamique of image','Dynamique de image') 

        if dlg.ShowModal() == wx.ID_OK: 
         self.text.SetValue("Dynamique:"+dlg.GetValue()) 
        dlg.Destroy()


class MiddlePanelBottom(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)
        self.SetBackgroundColour('black')
        canal=wx.Button(self,-1,"Variable",size=(140,30),pos=(100,0))
        dynamique=wx.Button(self,-1,"Dynamique",size=(140,30),pos=(240,0))
        file = wx.Button(self,-1,"File", size = (110,30),pos=(0,0))
        dynamique.SetBackgroundColour('white')
        canal.SetBackgroundColour('white')
        file.SetBackgroundColour('white')
        dynamique.Bind(wx.EVT_BUTTON, self.OnClick)
        file.Bind(wx.EVT_BUTTON, self.onOpen)
        self.load_options = "netCDF4 files (nc)|*.nc| Text files (txt) |*.txt| All files |*.*"

    def onOpen(self, event):
        wildcard = "netCDF4 files (*.nc)|*.nc"
        dialog = wx.FileDialog(self, "Open netCDF4 Files", wildcard=wildcard,
                               style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if dialog.ShowModal() == wx.ID_CANCEL:
            return
        path = dialog.GetPath()

        if os.path.exists(path):
            with open(path) as fobj:
                for line in fobj:
                    self.my_text.WriteText(line)

    def OnClick(self,event):
        dlg = wx.TextEntryDialog(self, 'Enter Dynamique of image','Dynamique de image') 

        if dlg.ShowModal() == wx.ID_OK: 
         self.text.SetValue("Dynamique:"+dlg.GetValue()) 
        dlg.Destroy()


class MiddlePanel(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent)

        top = MiddlePanelTop(self)
        bottom = MiddlePanelBottom(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(top, 2, wx.EXPAND)
        sizer.Add(bottom, 2, wx.EXPAND)
        self.SetSizer(sizer)


# ------------ RIGHT ------------

class RightPanelTop(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent)
        self.SetBackgroundColour('black')
        canal=wx.Button(self,-1,"Variable",size=(140,30),pos=(100,0))
        dynamique=wx.Button(self,-1,"Dynamique",size=(140,30),pos=(240,0))
        file = wx.Button(self,-1,"File", size = (110,30),pos=(0,0))
        dynamique.SetBackgroundColour('white')
        canal.SetBackgroundColour('white')
        file.SetBackgroundColour('white')
        dynamique.Bind(wx.EVT_BUTTON, self.OnClick)
        file.Bind(wx.EVT_BUTTON, self.onOpen)

    def onOpen(self, event):
        wildcard = "netCDF4 files (*.nc)|*.nc| HDF5 files (*.h5) |*.h5"
        dialog = wx.FileDialog(self, "Open netCDF4 Files| HDF5 files", wildcard=wildcard,
                               style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if dialog.ShowModal() == wx.ID_CANCEL:
            return

        path = dialog.GetPath()

        if os.path.exists(path):
            with open(path) as fobj:
                for line in fobj:
                    self.my_text.WriteText(line)

    def OnClick(self,event):
        dlg = wx.TextEntryDialog(self, 'Enter Dynamique of image','Dynamique de image') 

        if dlg.ShowModal() == wx.ID_OK: 
         self.text.SetValue("Dynamique:"+dlg.GetValue()) 
        dlg.Destroy()

class RightPanel(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)

        top = RightPanelTop(self)
        bottom = RightPanelBottom(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(top, 2, wx.EXPAND)
        sizer.Add(bottom, 2, wx.EXPAND)
        self.SetSizer(sizer)

class PanelBottom(wx.Panel):
    def __init__(self,parent):
        super().__init__(parent)
        self.SetBackgroundColour('grey77')
class PanelTop(wx.Panel):
    def __init__(self,parent):
        super().__init__(parent)
        left = SubPanelLeft(self)
        right = SubPanelRight(self)
        midlle = SubPanelMiddle(self)
        sizer1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer1.Add(left, 1, wx.EXPAND)
        sizer1.Add(midlle, 1, wx.EXPAND)
        sizer1.Add(right, 1, wx.EXPAND)

        self.SetSizer(sizer1)

class RightPanelBottom(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent)
        self.SetBackgroundColour('snow2')

        top = PanelTop(self)
        bottom = PanelBottom(self)
        sizer1 = wx.BoxSizer(wx.VERTICAL)
        sizer1.Add(top, 2, wx.EXPAND)
        sizer1.Add(bottom, 4, wx.EXPAND)
        self.SetSizer(sizer1)


class SubPanelLeft(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)
        self.SetBackgroundColour('black')

class SubPanelMiddle(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)
        self.SetBackgroundColour('black')

class SubPanelRight(wx.Panel):
    def __init__(self, parent):
        super().__init__(parent,style = wx.SUNKEN_BORDER)
        self.SetBackgroundColour('black')




app = wx.App()
frame = MainFrame(None).Show()
app.MainLoop()

推荐答案

要重新安排代码中的内容,以使用 panel 而不是新的 frame .虽然,只有在程序用户需要时才创建一个新框架,而现有的 panel 必须存在,无论是否需要!

It's a matter of rearranging things within the code to use a panel rather than a new frame. Although, a new frame is only created as needed by the user of the program, whilst an existing panel has to be there, whether it is needed or not!

我已经重新排列了先前的答案,以在另一个面板中显示 zoom ,但是出于我的一生,我不明白为什么您不利用内置的使用 NavigationToolbar2Wx 的matplotlib 工具栏.

I've rearranged a previous answer to show the zoom in another panel but for the life of me, I don't understand why you don't take advantage of the built in matplotlib toolbar using NavigationToolbar2Wx.

import wx
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
import matplotlib

class Window(wx.Frame):
    """ Fenêtre principale de l'application """

    def __init__(self, **kwargs):
        super().__init__(None, **kwargs)
        RootPanel(self)

class RootPanel(wx.Panel):
    """ Panel contenant tous les autres widgets de l'application """

    def __init__(self, parent):
        super().__init__(parent)

        panel_buttons = wx.Panel(self)
        panel_buttons_sizer = wx.GridSizer(1, 2, 0, 0)

        self.canvas_panel = CanvasPanel(self)
        self.zoom_panel = Zoom(parent=self)

        select_button = PickButton(
            panel_buttons,
            "netCDF4 files (nc)|*.nc",
            self.canvas_panel.load_from_file,
            label="Show on this window (nc)",
        )
        toplevel_select_button = TopLevelPickButton(
            panel_buttons,
            "Text files (txt)|*.txt|All files|*.*",
            label="Show on separate window (txt)",
        )
        panel_buttons_sizer.Add(select_button)
        panel_buttons_sizer.Add(toplevel_select_button)
        panel_buttons.SetSizer(panel_buttons_sizer)

        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel_buttons)
        sizer.Add(canvas_sizer)
        self.SetSizerAndFit(sizer)
        self.Show()

class PickButton(wx.Button):
    """ Bouton permettant de choisir un fichier """

    def __init__(self, parent, wildcard, func, **kwargs):
        # func est la méthode à laquelle devra être foruni le fichier sélectionné
        super().__init__(parent, **kwargs)
        self.wildcard = wildcard
        self.func = func
        self.Bind(wx.EVT_BUTTON, self.pick_file)

    def pick_file(self, evt):
        style = style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE
        with wx.FileDialog(
            self, "Pick files", wildcard=self.wildcard, style=style
        ) as fileDialog:
            if fileDialog.ShowModal() != wx.ID_CANCEL:
                chosen_file = fileDialog.GetPath()
                self.func(chosen_file)

class TopLevelPickButton(PickButton):
    """ Permet de choisir un fichier et d'ouvrir une toplevel """

    def __init__(self, parent, wildcard, **kwargs):
        super().__init__(parent, wildcard, self.create_toplevel, **kwargs)

    def create_toplevel(self, file_name):
        """ Ouvre une toplevel et affiche le graphique """
        self.win = TopLevelCanvas(self.Parent)
        self.win.canvas_panel.load_from_file(file_name)
        self.win.Show()

class CanvasPanel(wx.Panel):
    """ Panel du graphique matplotlib """
    def __init__(self, parent , size=(200,250)):
        super().__init__(parent)
        self.figure = Figure(figsize =(4,3))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.Size = self.canvas.Size
        self.parent = parent

    def load_from_file(self, file_name):
        """
        Méthode effectuant l'intermédiaire pour charger le fichier selon
        son type
        """
        self.axes = self.figure.add_subplot(111)
        if file_name.endswith(".nc"):
            self._load_nc(file_name)
        else:
            self._load_txt(file_name)
        self.canvas.draw()

    def _load_txt(self, file_name):
        self._load_nc(file_name)

    def _load_nc(self, file_name):
        """ Simule le chargement et affichage à partir d'un fichier nc """
        N = 100000
        x = np.linspace(0.0, 10.0, N)
        self.axes.plot(x, +np.sin(.2*np.pi*x), lw=3.5, c='b', alpha=.7)
        self.axes.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5)
        self.axes.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3)

        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=True,
                                       button=[1, 3],minspanx=5, minspany=5,
                                       spancoords='pixels',
                                       interactive=True,
                                       rectprops = dict(facecolor='None',edgecolor='red',alpha=0.5,fill=False))


    def line_select_callback(self, eclick, erelease):
        'eclick and erelease are the press and release events'
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        self.zoom_axes=[x1,x2,y1,y2]
        self.parent.zoom_panel.Update(self)


class Zoom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size=(200,250))
        self.Show()

    def Update(self,parent):
        #Load axis values of the selected rectangle
        zoom_axes=parent.zoom_axes

        #duplicate the plot from the main panel
        self.figure = Figure(figsize =(4,3))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)

        #Apply axis of drawn rectangle to the plot
        self.axes.axis(zoom_axes)

        N = 100000
        x = np.linspace(0.0, 10.0, N)
        self.axes.plot(x, +np.sin(.2*np.pi*x), lw=3.5, c='b', alpha=.7)
        self.axes.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5)
        self.axes.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3)
        self.canvas.draw()
        self.Refresh()

class TopLevelCanvas(wx.Frame):
    """ Fenêtre affichant uniquement un graph matplotlib """

    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.canvas_panel = CanvasPanel(self)
        self.zoom_panel = Zoom(parent=self)
        self.Size = self.canvas_panel.Size
        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)
        self.SetSizerAndFit(canvas_sizer)
        self.Show()

class App(wx.App):
    def OnInit(self):
        win = Window(title="A test dialog", size=(1000, 800))
        win.Show()
        return True

if __name__ == "__main__":
    app = App()
    app.MainLoop()

这篇关于在矩形类缩放中选择区域时出错(wx.frame)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆