如何使用带有补丁矩形的艺术家同时移动 2 个 retcngale [英] how use artists with patch rectangle to move 2 retcngale in same time

查看:23
本文介绍了如何使用带有补丁矩形的艺术家同时移动 2 个 retcngale的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在两个缩放面板1和缩放面板2中使用矩形补丁这个想法是必须将矩形修补到面板中,当我在缩放面板中移动矩形时,两个矩形可以同时移动 1 在缩放面板 2 中的同一时间和相同区域中移动

i use rectangle patch in two zoom panel1 and zoom panel 2 the idea is to have to rectangle patch in to panel the two rectangle can move in the same time when i move the rectangle in zooom 1 is move in the same time and same area in the zoom panel 2

我如何在这个例子中使用带有 matplotlib 的矩形艺术家

how can i use rectangle artist with matplotlib in this exemple

import wx
from numpy import arange, sin, pi,cos
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.patches as patches

class MainFrame(wx.Frame):
    def __init__(self, parent ):
        wx.Panel.__init__(self, parent,name="Main", size = (800,800))
        self.Panel = Panel(self)
       

class Panel(wx.Panel):
    def __init__(self,parent):
        super().__init__(parent)
        panel = wx.Panel(self)
        self.canvas_panel = CanvasPanel(self)
        self.zoom_panel=Zoom(parent=self)
        self.zoom_panel2=Zoom2(parent=self)
        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel2,1,wx.EXPAND)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel)
        sizer.Add(canvas_sizer)
        self.SetSizerAndFit(sizer)
        self.Show()

class CanvasPanel(wx.Panel):
    """ Panel du graphique matplotlib """
    def __init__(self, parent , size=(200,350)):
        super().__init__(parent)
        self.figure = Figure(figsize =(4,4))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        self.Size = self.canvas.Size
        self.parent = parent
        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.axes.get_xaxis().set_visible(False)
        self.axes.get_yaxis().set_visible(False)
        self.canvas.mpl_connect('button_press_event', self.on_press)
        x = y = 0.02
        self.rect = patches.Rectangle((x, y), 0.4,0.4,edgecolor='g', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)
        self.axes.plot()

    def on_press(self, click):
        x1, y1 = click.xdata, click.ydata
        zx1 = x1 - 0.2
        zy1 = y1 - 0.2
        zx2 = x1 + 0.2
        zy2 = y1 + 0.2
        self.rect.set_x(x1 - 0.2) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 0.2) #Move the rectangle and centre it on the Y click point


        self.axes.plot()
        self.canvas.draw()
        self.zoom_axes=[zx1,zx2,zy1,zy2]
        self.parent.zoom_panel.Update(self)
        self.parent.zoom_panel2.Update(self)

        

class Zoom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size=(200,200))
        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,4))
        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)
        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.axes.get_xaxis().set_visible(False)
        self.axes.get_yaxis().set_visible(False)
        self.canvas.mpl_connect('button_press_event', self.on_press)
        x = y = 0.01
        self.rect = patches.Rectangle((x, y), 0.02, 0.02,edgecolor='g', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)
        self.axes.plot()


        
    def on_press(self, click):
        x1, y1 = click.xdata, click.ydata
        zx1 = x1 - 0.01
        zy1 = y1 - 0.01
        zx2 = x1 + 0.01
        zy2 = y1 + 0.01
        self.rect.set_x(x1 - 0.01) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 0.01) #Move the rectangle and centre it on the Y click point
        

        self.axes.plot()
        self.canvas.draw()
        self.zoom_axes=[zx1,zx2,zy1,zy2]

class Zoom2(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size=(200,200))
        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,4))
        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)
        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.axes.get_xaxis().set_visible(False)
        self.axes.get_yaxis().set_visible(False)
        self.canvas.mpl_connect('button_press_event', self.on_press)
        x = y = 0.01
        self.rect = patches.Rectangle((x, y), 0.02, 0.02,edgecolor='g', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)
        self.axes.add_artist(self.rect)
        
        self.axes.plot()

        
    def on_press(self, click):
        x1, y1 = click.xdata, click.ydata
        zx1 = x1 - 0.01
        zy1 = y1 - 0.01
        zx2 = x1 + 0.01
        zy2 = y1 + 0.01
        self.rect.set_x(x1 - 0.01) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 0.01) #Move the rectangle and centre it on the Y click point
        

        self.axes.plot()
        self.canvas.draw()
        self.zoom_axes=[zx1,zx2,zy1,zy2]
       
       

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

谢谢大家

推荐答案

所做的更改:

  • 添加了 2 个缩放面板之间的通信.每个都可以通过 add_subscriber(subscriber_name, action_to_make) 添加一个订阅者,并且每次其中一个按下它都会调用所有 action_to_make(click).
  • 由于 Zoom 和 Zoom2 基本上是同一个类的 2 个实例(具有相同的代码),我删除了第二个类的定义,并制作了 zoom_panelzoom_panel2 不同的实例同班.
  • 将 Zoom 更改为仅实例化 Figure 和 Rectangle 以及所有这些仅一次并更新它们,而不是创建新实例并将其放置在旧实例之上.
  • Added communication between 2 Zoom panels. Each can have a subscriber added by add_subscriber(subscriber_name, action_to_make) and every time one of them pressed it'll call all action_to_make(click).
  • As Zoom and Zoom2 are basically 2 instances of same class (had identical code) I've removed a definition of the 2nd class and made zoom_panel and zoom_panel2 different instances of same class.
  • Changed Zoom to only instantiate Figure and Rectangle and all that only once and updating them instead of creating a new instance and placing it atop the old one.
import wx
from numpy import arange, sin, pi,cos
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.patches as patches

class MainFrame(wx.Frame):
    def __init__(self, parent ):
        wx.Panel.__init__(self, parent,name="Main", size = (1000,800))
        self.Panel = Panel(self)


class Panel(wx.Panel):
    def __init__(self,parent):
        super().__init__(parent)
        panel = wx.Panel(self)
        self.canvas_panel = CanvasPanel(self)
        self.zoom_panel=Zoom(parent=self)
        self.zoom_panel2=Zoom(parent=self)

        self.zoom_panel.add_subscriber("zoom_panel2", self.zoom_panel2.on_notified)
        self.zoom_panel2.add_subscriber("zoom_panel", self.zoom_panel.on_notified)

        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel,1,wx.EXPAND)
        canvas_sizer.Add(self.zoom_panel2,1,wx.EXPAND)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel)
        sizer.Add(canvas_sizer)
        self.SetSizerAndFit(sizer)
        self.Show()

class CanvasPanel(wx.Panel):
    """ Panel du graphique matplotlib """
    def __init__(self, parent , size=(200,350)):
        super().__init__(parent)
        self.figure = Figure(figsize =(4,4))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        self.Size = self.canvas.Size
        self.parent = parent
        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.axes.get_xaxis().set_visible(False)
        self.axes.get_yaxis().set_visible(False)
        self.canvas.mpl_connect('button_press_event', self.on_press)
        x = y = -0.2
        self.rect = patches.Rectangle((x, y), 0.4,0.4,edgecolor='g', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)
        self.axes.plot()

    def on_press(self, click):
        x1, y1 = click.xdata, click.ydata
        zx1 = x1 - 0.2
        zy1 = y1 - 0.2
        zx2 = x1 + 0.2
        zy2 = y1 + 0.2
        self.rect.set_x(x1 - 0.2) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 0.2) #Move the rectangle and centre it on the Y click point


        self.axes.plot()
        self.canvas.draw()
        self.zoom_axes=[zx1,zx2,zy1,zy2]
        self.parent.zoom_panel.Update(self)
        self.parent.zoom_panel2.Update(self)



class Zoom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size=(200,200))
        self.Show()
        self.subscriber_list = {}
        #init figure&canvas
        self.figure = Figure(figsize =(4,4))
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_subplot(111)
        self.axes.get_xaxis().set_visible(False)
        self.axes.get_yaxis().set_visible(False)
        self.axes.axis([-0.2,0.2,-0.2,0.2]) # set default display window
        self.canvas.mpl_connect('button_press_event', self.on_press)
        #add rectangle
        x = y = 0.01
        self.rect = patches.Rectangle((x, y), 0.02, 0.02,edgecolor='g', alpha=1, fill=None, label='Label')
        self.axes.add_patch(self.rect)

        #first display
        self.axes.plot()
        self.canvas.draw()

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

        #clear Axes
        self.axes.clear()

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



        #draw same plot as on the main panel
        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s, 'C0')

        #draw rectangle
        self.axes.add_patch(self.rect)

        #display
        self.axes.plot()
        self.canvas.draw()

    def on_press(self, click):
        self.perform_press(click)
        self.notify_subscribers(click)


    def perform_press(self, click):
        x1, y1 = click.xdata, click.ydata
        zx1 = x1 - 0.01
        zy1 = y1 - 0.01
        zx2 = x1 + 0.01
        zy2 = y1 + 0.01
        self.rect.set_x(x1 - 0.01) #Move the rectangle and centre it on the X click point
        self.rect.set_y(y1 - 0.01) #Move the rectangle and centre it on the Y click point

        self.axes.plot()
        self.canvas.draw()
        self.zoom_axes=[zx1,zx2,zy1,zy2]

    def notify_subscribers(self, click):
        for subscriber in self.subscriber_list:
            self.subscriber_list.get(subscriber)(click)

    # adds a new subscriber to the list. "name" is a subscriber identifier, "action" is called as "action(name)" every time this element is clicked
    def add_subscriber(self, name, action):
        self.subscriber_list[name]=action

    def on_notified(self, click):
        #Do something here
        #print("Zoom received notification from Zoom2: ", click)
        self.perform_press(click)


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

这篇关于如何使用带有补丁矩形的艺术家同时移动 2 个 retcngale的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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