Skip to content

Commit

Permalink
feat: brush rectangle lasso (#184)
Browse files Browse the repository at this point in the history
* feat: add support for brush and rectangle lasso types

* feat: allow to easily hide buttons

* docs: update API docs of `scatter.lasso()`

* docs: describe brush and rectangle lasso selections

* chore: update vitepress

* chore: use internal button widget and anywidgetify the divider

* fix: background histogram render bug

* fix: ensure NAs are skipped for the histgram

And define categorical data as data where at least one category appears more than once

* feat: allow specifying which properties should feature a histogram

* feat: visualize brush size

* refactor: simplify `tooltip_histograms` handling

* chore: update regl-scatterplot

* fix: hide tooltip on lasso start
  • Loading branch information
flekschas authored Feb 13, 2025
1 parent e230e48 commit f665049
Show file tree
Hide file tree
Showing 25 changed files with 1,599 additions and 384 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v0.21.0

- Feat: add support for brush and rectangle lasso types.
- Feat: expose lasso selection polygon via `scatter.widget.lasso_polygon_selection`
- Feat: enable merging of lasso selection upon holding down the [meta key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey) and deselected points upon holding down the [alt key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/altKey).

## v0.20.0

- Feat: add support for showing a scatter plot in full-screen mode. In full-screen mode you can easily customize and up-scale the resolution for better exporting in PNG.
Expand Down
15 changes: 10 additions & 5 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ from jscatter import HLine, VLine
scatter.annotations([HLine(42), VLine(42)])
```

### scatter.tooltip(_enable=Undefined_, _properties=Undefined_, _histograms=Undefined_, _histograms_bins=Undefined_, _histograms_ranges=Undefined_, _histograms_size=Undefined_, _preview=Undefined_, _preview_type=Undefined_, _preview_text_lines=Undefined_, _preview_image_background_color=Undefined_, _preview_image_position=Undefined_, _preview_image_size=Undefined_, _preview_audio_length=Undefined_, _preview_audio_loop=Undefined_, _preview_audio_controls=Undefined_, _size=Undefined_) {#scatter.tooltip}
### scatter.tooltip(_enable=Undefined_, _properties=Undefined_, _histograms=Undefined_, _histograms_bins=Undefined_, _histograms_ranges=Undefined_, _histograms_size=Undefined_, _preview=Undefined_, _preview_type=Undefined_, _preview_text_lines=Undefined_, _preview_image_background_color=Undefined_, _preview_image_position=Undefined_, _preview_image_size=Undefined_, _preview_image_height=Undefined_, _preview_audio_length=Undefined_, _preview_audio_loop=Undefined_, _preview_audio_controls=Undefined_, _size=Undefined_) {#scatter.tooltip}

Set or get the tooltip settings.

Expand All @@ -412,7 +412,7 @@ Set or get the tooltip settings.

- `properties` is a list of string specifying for which visual or data properties to show in the tooltip. The visual properties can be some of `x`, `y`, `color`, `opacity`, and `size`. Note that visual properties are only shown if they are actually used to data properties. To reference other data properties, specify a column of the bound DataFrame by its name.

- `histograms` is a Boolean specifying if the tooltip should show histograms of the properties
- `histograms` is a Boolean or list of property names specifying if histograms should be shown. When set to `True`, the tooltip will show histograms for all properties. Alternatively, you can provide a list of properties for which you want to show a histogram.

- `histograms_bins` is either an Integer specifying the number of bins of all numerical histograms or a dictionary of property-specific number of bins. The default is `20`.

Expand All @@ -436,6 +436,8 @@ Set or get the tooltip settings.

See https://developer.mozilla.org/en-US/docs/Web/CSS/background-size for details on the behavior.

- `preview_image_height` The height of the image container pixels. By default, it is `None`, which makes the height deffault to 6em.

- `preview_audio_length` is an integer specifying the number of seconds of an audio preview that should be played. By default (`None`), the audio file is played from the start to the end.

- `preview_audio_loop` is a Boolean specifying if the audio preview is indefinitely looped for the duration the tooltip is shown.
Expand Down Expand Up @@ -553,16 +555,18 @@ scatter.mouse(mode='lasso')
```


### scatter.lasso(_color=Undefined_, _initiator=Undefined_, _min_delay=Undefined_, _min_dist=Undefined_, _on_long_press=Undefined_) {#scatter.lasso}
### scatter.lasso(_type=Undefined_, _color=Undefined_, _initiator=Undefined_, _min_delay=Undefined_, _min_dist=Undefined_, _on_long_press=Undefined_, _brush_size=Undefined_) {#scatter.lasso}

Get or set the lasso for selecting multiple points.

**Arguments:**
- `type` is a string specifying the lasso type. Must be one of `'freeform'`, `'brush'`, or `'rectangle'`.
- `color` is a string referring to a Matplotlib-compatible color.
- `initiator` is a Boolean value to specify if the click-based lasso initiator should be enabled or not.
- `min_delay` is an integer specifying the minimal delay in milliseconds before a new lasso point is stored. Higher values will result in more coarse grain lasso polygons but might be more performant.
- `min_dist` is an integer specifying the minimal distance in pixels that the mouse has to move before a new lasso point is stored. Higher values will result in more coarse grain lasso polygons but might be more performant.
- `on_long_press` is a Boolean value specifying if the lasso should be activated upon a long press.
- `brush_size` is an integer specifying the size of the brush in pixels. This has only an effect if `type` is set to `'brush'`'. Defaults to `24`.

**Returns:** either the lasso properties when all arguments are `Undefined` or `self`.

Expand Down Expand Up @@ -718,8 +722,8 @@ The widget (`scatter.widget`) has the following properties, which you can think
While you can adjust these properties directly, the [`Scatter` methods](#methods) are the idiomatic and recommended way to set widget properties.
:::

| Name | Type <div style="min-width:250px"/> | Default <div style="min-width:180px"/> | Allow None | Read Only | Note <div style="min-width:320px"/> |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ---------- | --------- | ------------- |
| Name | Type <div style="min-width:250px"/> | Default <div style="min-width:180px"/> | Allow None | Read Only | Note <div style="min-width:320px"/> |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | --------- | ------------- |
| `dom_element_id` | str | | | `True` | For debugging |
| `data` | 2D numerical array | | | | |
| `prevent_filter_reset` | bool | `False` | | | |
Expand Down Expand Up @@ -788,6 +792,7 @@ While you can adjust these properties directly, the [`Scatter` methods](#methods
| `tooltip_preview_image_background_color` | `"auto"` \| str | `"auto"` | | | |
| `tooltip_preview_image_position` | `"top"`<br/>\| `"left"`<br/>\| `"right"`<br/>\| `"bottom"`<br/>\| `"center"` | `"center"` | `True` | | |
| `tooltip_preview_image_size` | `"contain"` \| `"cover"` | `"contain"` | `True` | | |
| `tooltip_preview_image_height` | int | `None` | `True` | | |
| `tooltip_preview_audio_length` | int | `None` | `True` | | |
| `tooltip_preview_audio_loop` | bool | `False` | | | |
| `tooltip_preview_audio_controls` | bool | `True` | | | |
Expand Down
64 changes: 59 additions & 5 deletions docs/interactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,66 @@ closed it'll turn blue. At this point the lasso is active.
<div class="overlay">Hover to play video</div>
</div>

Alternatively, you can click on the crosshair icon in the top-left of the
scatter plot to permanently activate the lasso.
Once the lasso is active, keep holding down your primary mouse button and move
your mouse cursor around the points you want to select. Finally, release your
primary mouse key.

To select points once the lasso is active, keep holding down your primary mouse
button and move your mouse cursor around the points you want to select. Finally,
release your primary mouse key.
::: info
To permanently activate the lasso, you can click on the crosshair icon in the
top-left of the scatter plot.
:::

### Add and Remove Selected Points

To add more points to an existing selection, hold down the [_meta_ key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey) as you
lasso select the points you want to add. To remove points from a selection, hold
down the [_alt_ key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/altKey) as you lasso select the points you want to remove.

<div class="video">
<video loop muted playsinline width="1256" data-name="interactions-lasso-add-remove">
<source
src="/videos/interactions-lasso-add-remove-light.mp4"
type="video/mp4"
/>
</video>
<div class="overlay">Hover to play video</div>
</div>

::: info
On macOS, the meta key is `Command` or `` and the alt key is `Option` or ``.
:::

### Brush and Rectangle Lasso Selections

Beyond this _freeform_ lasso selection, Jupyter Scatter also offers
_rectangular_ and _brush_ style lasso selections. You can change the lasso type
either via the _lasso_ button in the top-left corner of the plot or via
`scatter.lasso(type=lasso_type)`, where `lasso_type` must be one of
`'freeform'`, `'brush'`, or `'rectangle'`.

Below is an example of the brush lasso selection.

<div class="video">
<video loop muted playsinline width="1256" data-name="interactions-lasso-brush">
<source
src="/videos/interactions-lasso-brush-light.mp4"
type="video/mp4"
/>
</video>
<div class="overlay">Hover to play video</div>
</div>

And finally an example of the classic rectangular lasso selection.

<div class="video">
<video loop muted playsinline width="1256" data-name="interactions-lasso-rectangle">
<source
src="/videos/interactions-lasso-rectangle-light.mp4"
type="video/mp4"
/>
</video>
<div class="overlay">Hover to play video</div>
</div>

## Filter Points

Expand Down
Loading

0 comments on commit f665049

Please sign in to comment.