Rectangle selection#

In this example, we will use a custom drawing tool to draw rectangles on a 2D figure. The data inside the rectangles will be summed along the vertical dimension, and displayed on a one-dimensional plot below the image.

[1]:
%matplotlib widget
import plopp as pp
import scipp as sc

We first generate some data that contains three bands of peaks that all have different spreads.

[2]:
from plopp.data.examples import three_bands

da = three_bands()

We then construct our custom tool, using Mpltoolbox’s Rectangles tool, and inheriting from Plopp’s DrawingTool.

[3]:
from plopp.widgets.drawing import DrawingTool
from functools import partial
from mpltoolbox import Rectangles


def vertical_sum(da, rect_info):
    """
    Function that slices the data according to the
    rectangle size/position, and sums along the
    vertical dimension.
    """
    x = rect_info['x']
    y = rect_info['y']
    b = min(y['bottom'], y['top'])
    t = max(y['bottom'], y['top'])
    l = min(x['left'], x['right'])
    r = max(x['left'], x['right'])
    return da[y['dim'], b:t][x['dim'], l:r].sum(y['dim'])


def _get_rect_info(artist, figure):
    """
    Convert the raw rectangle info to a dict containing the dimensions of
    each axis, and values with units.
    """
    return lambda: {
        'x': {
            'dim': figure.canvas.dims['x'],
            'left': sc.scalar(artist.xy[0], unit=figure.canvas.units['x']),
            'right': sc.scalar(
                artist.xy[0] + artist.width, unit=figure.canvas.units['x']
            ),
        },
        'y': {
            'dim': figure.canvas.dims['y'],
            'bottom': sc.scalar(artist.xy[1], unit=figure.canvas.units['y']),
            'top': sc.scalar(
                artist.xy[1] + artist.height, unit=figure.canvas.units['y']
            ),
        },
    }


RectangleTool = partial(
    DrawingTool, tool=Rectangles, get_artist_info=_get_rect_info, icon='vector-square'
)

Finally, we create our visualization interface with two figures, adding our new tool to the toolbar.

[4]:
from plopp.widgets import Box

data_node = pp.Node(da)

f2d = pp.imagefigure(data_node, norm='log')
f1d = pp.linefigure()

r = RectangleTool(figure=f2d, input_node=data_node, func=vertical_sum, destination=f1d)
f2d.toolbar['roi'] = r

box = Box([f2d, f1d])
[6]:
box
[6]:
[7]:
pp.show_graph(data_node)
[7]:
../_images/gallery_rectangle-selection_10_0.svg