Python 3.x 为什么矩形选择器可以';t在地块内移动

Python 3.x 为什么矩形选择器可以';t在地块内移动,python-3.x,matplotlib,wxpython,Python 3.x,Matplotlib,Wxpython,当我添加了一个矩形选择器时,我有一个应用程序,但当我点击时无法移动 我需要在另一个框架中画出矩形内的区域,我怎么能做到呢? 我觉得我的代码有问题,矩形不能在绘图中移动,我不能移动!! 然后我如何在其他帧中绘制区域选择 谢谢大家 import wx import numpy as np from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas from matplotlib.figure impo

当我添加了一个矩形选择器时,我有一个应用程序,但当我点击时无法移动 我需要在另一个框架中画出矩形内的区域,我怎么能做到呢? 我觉得我的代码有问题,矩形不能在绘图中移动,我不能移动!! 然后我如何在其他帧中绘制区域选择

谢谢大家

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 netCDF4





def line_select_callback(eclick, erelease):
    x1, y1 = eclick.xdata, eclick.ydata
    x2, y2 = erelease.xdata, erelease.ydata
    print("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
    #print(" The button you used were: %s %s" % (eclick.button, erelease.button))


class Window(wx.Frame):


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



class RootPanel(wx.Panel):


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

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

        canvas_panel = CanvasPanel(self)

        select_button = PickButton(
            panel_buttons,
            "netCDF4 files (nc)|*.nc",
            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)


        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel_buttons)
        sizer.Add(canvas_panel)
        self.SetSizer(sizer)


class PickButton(wx.Button):


    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):


    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):

    def __init__(self, parent , size=(200,250)):
        super().__init__(parent)
        self.figure = Figure(figsize =(8,7))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.Size = self.canvas.Size

    def load_from_file(self, file_name):
        """

        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()

    #print(" The button you used were: %s %s" % (eclick.button, erelease.button))
    def _load_nc(self, file_name):

        t = np.arange(0.0, 8.0, 0.01)
        s = np.sin(3 * np.pi * t)
        self.axes.plot(t, s)



        # drawtype is 'box' or 'line' or 'none'
        RS = RectangleSelector(self.axes,line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[3],  
                                       minspanx=5, minspany=5,
                                       spancoords='pixels',
                                       interactive=True)


        RS.to_draw.set_visible(True)
        RS.extents = (1,20,1,15)
        self.figure.canvas.draw()
        plt.show()

class TopLevelCanvas(wx.Frame):

    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.canvas_panel = CanvasPanel(self)
        self.Size = self.canvas_panel.Size


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()

< P>矩形拖动矩形中间的方块移动矩形。
我确信有很多方法可以使用
matplotlib
在另一个绘图中绘制选定的矩形,这是一种手动缩放,但我无论如何都不是
matplotlib
专家。
以下内容通过存储矩形选择的轴,然后调用一个新的帧来实现我认为您想要的效果,在该帧中,绘图重复,但轴已调整。
如果新帧失去焦点,它将自动取消,因此不会出现多个
Zoom
窗口。
希望有帮助

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)

        canvas_panel = CanvasPanel(self)

        select_button = PickButton(
            panel_buttons,
            "netCDF4 files (nc)|*.nc",
            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)

        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 = 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 =(8,7))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.Size = self.canvas.Size
        self.zoom_axis = []

    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 """
        t = np.arange(0.0, 8.0, 0.01)
        s = np.sin(3 * np.pi * t)
        self.axes.plot(t, s)



    # drawtype is 'box' or 'line' or 'none'

        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=5,fill=False))


        #self.RS.to_draw.set_visible(True)
        #self.figure.canvas.draw()
        #self.RS.extents = (0,1,0,1)

    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_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 = 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 =(8,7))
        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.plot(t, s)
        self.canvas.draw()
        self.Show()

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

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.Size = self.canvas_panel.Size


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()

如果删除
plt.show()
,会发生什么,这在这里毫无意义?当我删除plt.show()时,什么都没有发生,我无法移动矩形选择!!好的,无论如何把它取下来。同样,将
RS
作为一个实例变量,就像您对其他对象所做的那样,
self.RS
。移动矩形很好,我将self添加到行中:
self.RS=RectangleSelector。。。。。self.RS.to_draw.set_visible(True)self.RS.extends,self.figure.canvas.draw()
但我有一个问题,如何删除矩形内的红色?透明矩形?谢谢u@ImportanceOfBeingErnest为什么矩形移动得快?如何使矩形选择器移动得快?感谢您的帮助我的应用程序有问题我在运行代码回溯时出错(上次调用):文件“C:\Users\majdoulina\Anaconda3\lib\site packages\matplotlib\cbook\u init_uuuuuuuz.py”,第215行,进程中func(*args,**kwargs)文件“C:\Users\majdoulina\Anaconda3\lib\site packages\matplotlib\widgets.py”,第1597行,在release self.onselect(self.eventpress,self.eventrelease)类型错误:line_select_callback()缺少1个必需的位置参数:“errease”您的代码具有函数
line_select_callback(eclick,errease)
在类之外定义,我将其移动到
CanvasPanel
类中。我怀疑这就是问题所在,因为一旦它在类中,它需要3个参数
self
eclick
erelease
。我在第二个应用程序中应用代码的问题代码是第一个应用程序的代码,但当我对第二个应用程序执行相同操作时,但当我选择rectangelselector以绘制缩放帧时,出现错误的是她我的第二个应用程序[如果您可以帮助提前感谢您如果我添加第二个面板rightpanel并将zoom(wxframe)更改为zoom(wx.panel),是否可以在第二个面板中添加缩放?再次感谢您