如何让2个矩形选择器同时在同一区域移动

how make 2 rectangle selector move in the same times and in the same area

我需要定义 2 个在同一时间和同一区域移动的矩形选择器,当我移动彼此时,我该怎么做?

这是一个简单的代码,在 2 个面板和 2 个矩形中有 2 个绘图

可以让两个矩形同时移动,因为我没有在网络或 matplotlib 中找到任何例子

我使用 wxpython 4 python3.6

import wx
from numpy import arange, sin, pi,cos
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.widgets import RectangleSelector
from matplotlib.figure import Figure



class MainFrame(wx.Frame):
    def __init__(self, parent ):
        wx.Panel.__init__(self, parent,name="Main", size = (600,800))
        Top = PanelTop(self)
        Bottom = PanelBottom(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(Top, 1, wx.EXPAND)
        sizer.Add(Bottom, 1, wx.EXPAND)
        self.SetSizer(sizer)


class PanelTop(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size = (300,300))
        self.SetBackgroundColour('white')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)


        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)



    def line_select_callback(self, eclick, erelease):
         x1, y1 = eclick.xdata, eclick.ydata
         x2, y2 = erelease.xdata, erelease.ydata


class PanelBottom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self, parent, size = (300,300))
        self.SetBackgroundColour('grey77')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)

        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)



    def line_select_callback(self, eclick, erelease):
         x1, y1 = eclick.xdata, eclick.ydata
         x2, y2 = erelease.xdata, erelease.ydata



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

提前致谢

我不知道这是否是应该的方式,但这是一种方式。
我在适当的地方评论了代码。
该方法只是简单地抓取第一个 Rectangle 的坐标,将它们强制放入第二个 Rectangle 中,然后重新绘制它。
第二个矩形被设置为非活动状态,因为它是第一个 and 的从属对象,如果它不是非活动状态,角落和中间的控制点将无法与矩形一起移动。这使我相信可能有一种不那么棘手的方法可以达到相同的结果。

import wx
from numpy import arange, sin, pi,cos
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.widgets import RectangleSelector
from matplotlib.figure import Figure

class MainFrame(wx.Frame):
    def __init__(self, parent ):
        wx.Panel.__init__(self, parent,name="Main", size = (600,800))
        self.Top = PanelTop(self)
        self.Bottom = PanelBottom(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.Top, 1, wx.EXPAND)
        sizer.Add(self.Bottom, 1, wx.EXPAND)
        self.SetSizer(sizer)

class PanelTop(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size = (300,300))
        self.SetBackgroundColour('white')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)


        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)

    def line_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        rect = self.RS.artists[0] # Rectangle artist
        slave_rect = self.Parent.Bottom.RS.artists[0] # Rectangle artist
        slave_canvas = self.Parent.Bottom.canvas

        # Force new positional values into slave rectangle
        slave_rect.set_x(x1)
        slave_rect.set_y(y1)
        slave_rect.set_width(x2-x1)
        slave_rect.set_height(y2-y1)
        slave_rect.update(dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        #Force visible in case slave rectangle has been clicked on
        slave_rect.set_visible(True)
        #Redraw slave rectangle
        slave_canvas.draw()

class PanelBottom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self, parent, size = (300,300))
        self.SetBackgroundColour('grey77')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)

        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=False, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)

    def line_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata

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