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