0

我正在尝试将两个矩形选择器(docs)添加到我的图中:

目前,我在按下键盘键时创建Area和类(都包含矩形选择器)。Background按另一个键后,我创建了另外两个类,它们从AreaBackground类中获取属性。

import numpy as np
import matplotlib.pyplot as plt


from matplotlib.widgets import RectangleSelector

class AreaSelector():
    """ lets the user select an area"""
    def __init__(self, fig, ax, im):
        self.x1                         = None
        self.y1                         = None
        self.x2                         = None
        self.y2                         = None

        self.observers                  = []

        toggle_selector.RS              = RectangleSelector(ax, self.line_select_callback,
                                                            drawtype='box', useblit=True,
                                                            button=[1],  # don't use middle button
                                                            minspanx=1, minspany=1,
                                                            spancoords='pixels',
                                                            interactive=True,
                                                            rectprops=dict(facecolor='green',edgecolor='black', alpha=0.3))

    def line_select_callback(self, eclick, erelease):
        """ gets the positions and sends them to the observer"""
        'eclick and erelease are the press and release events'
        self.x1, self.y1 = eclick.xdata, eclick.ydata
        self.x2, self.y2 = erelease.xdata, erelease.ydata
        self.set_new_position(self.x1, self.y1, self.x2, self.y2)

    def set_new_position(self, x1, y1, x2, y2):
        """ informs the observer about the new positions"""
        self.x1                     = x1
        self.y1                     = y1
        self.x2                     = x2
        self.y2                     = y2 
        for callback in self.observers:
            callback(self.x1, self.y1, self.x2, self.y2)

    def bind_to(self, callback):
        """ binds the observer"""
        self.observers.append(callback)

class ExtractSpectra():
    def __init__(self, cube, area_selector):
        """ class that will do fancy things with the selected area"""
        self.cube                   = cube
        self.x1_area                = None
        self.y1_area                = None
        self.x2_area                = None
        self.y2_area                = None
        self.sum_area               = None
        self.sum_background         = None

        self.area_selector          = area_selector

        self.area_selector.bind_to(self.update_position_area)

    def update_position_area(self, x1, y1, x2, y2):
        """ updates position upon changes in Area Selector"""
        self.x1_area                = x1
        self.y1_area                = y1
        self.x2_area                = x2
        self.y2_area                = y2

    def get_spectra(self): 
        """ some math on the selected area"""
        if self.x1_area != None:
            self.sum_area           = np.sum(self.cube[np.round(self.y1_area,0).astype(int) : np.round(self.y2_area,0).astype(int),
                                                       np.round(self.x1_area,0).astype(int) : np.round(self.x2_area,0).astype(int)])
            print(self.sum_area)


        else:
            print("Area not selected!")


class BackgroundSelector():
    """ lets the user select an area, same structur as other selector"""
    def __init__(self, fig, ax, im):
        self.x1                     = None
        self.y1                     = None
        self.x2                     = None
        self.y2                     = None

        self.observers              = []

        toggle_selector.RS          = RectangleSelector(ax, self.line_select_callback,
                                                            drawtype='box', useblit=True,
                                                            button=[1],  # don't use middle button
                                                            minspanx=1, minspany=1,
                                                            spancoords='pixels',
                                                            interactive=True,
                                                            rectprops=dict(facecolor='red',edgecolor='black', alpha=0.3))        

    def line_select_callback(self, eclick, erelease):
        'eclick and erelease are the press and release events'
        self.x1, self.y1            = eclick.xdata,   eclick.ydata
        self.x2, self.y2            = erelease.xdata, erelease.ydata
        self.set_new_position(self.x1, self.y1, self.x2, self.y2)

    def set_new_position(self, x1, y1, x2, y2):
        self.x1                     = x1
        self.y1                     = y1
        self.x2                     = x2
        self.y2                     = y2 
        for callback in self.observers:
            callback(self.x1, self.y1, self.x2, self.y2)

    def bind_to(self, callback):
        self.observers.append(callback)

class ExtractBackground():
    def __init__(self, cube, background_selector):
        self.cube                   = cube
        self.x1_background          = None
        self.y1_background          = None
        self.x2_background          = None
        self.y2_background          = None
        self.sum_background         = None

        self.background_selector    = background_selector

        self.background_selector.bind_to(self.update_position_background)


    def update_position_background(self, x1, y1, x2, y2):
        self.x1_background          = x1
        self.y1_background          = y1
        self.x2_background          = x2
        self.y2_background          = y2


    def get_background(self):
        if self.x1_background != None:
            self.sum_background     = np.sum(self.cube[np.round(self.y1_background,0).astype(int) : np.round(self.y2_background,0).astype(int),
                                                       np.round(self.x1_background,0).astype(int) : np.round(self.x2_background,0).astype(int)])
            print(self.sum_background)            
        else:
            print("Background not selected!")







def sample_plot():
    fig                             = plt.figure()
    ax                              = plt.subplot()

    im                              = np.ones((100,100))*-1
    im[10:20,10:40]                 = 1.

    img                             = ax.imshow(im, origin='lower', cmap='inferno')

    return(fig, ax, img, im)





if __name__ == "__main__":



    def toggle_selector( event):
        print(' Key pressed.')        

        if event.key in ['E', 'e']:
            area_selector                   = AreaSelector(fig, ax, im)
            extractor_area                  = ExtractSpectra(im, area_selector)
            global extractor_area
            print('e')

        if event.key in ['C', 'c']:
            background_selector             = BackgroundSelector(fig, ax, im)
            extractor_background            = ExtractBackground(im, background_selector)
            global extractor_background
            print('c')

        if event.key in ['Y', 'y']:

            try: extractor_area.get_spectra()
            except: print('extrator area not designated')
            try: extractor_background.get_background()
            except: print('background area not designated')
            print('y')


    fig, ax, img, im                = sample_plot()


    plt.connect('key_press_event', toggle_selector)
    plt.show()

这基本上可以正常工作(即使我对我编写这个的方式并不满意[为什么 4 个类?,使用全局变量等会认出来的!)

在此处输入图像描述

发生了什么?如果你有心情,我怎么能做得更好?我正在努力提高我的编程游戏!

谢谢!

4

0 回答 0