Thanks to visit codestin.com
Credit goes to github.com

Skip to content

create BaseSelector, heatmap also works with LinearSelector and LinearRegionSelector #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions docs/source/api/graphics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,11 @@ Line Stack
.. autoclass:: fastplotlib.graphics.line_collection.LineStack
:members:
:inherited-members:

Line Slider
###########

.. autoclass:: fastplotlib.graphics.line_slider.LineSlider
:members:
:inherited-members:

Heatmap
#######

.. autoclass:: fastplotlib.graphics.heatmap.HeatmapGraphic
.. autoclass:: fastplotlib.graphics.image.HeatmapGraphic
:members:
:inherited-members:

Expand Down
15 changes: 15 additions & 0 deletions docs/source/api/selectors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.. _api_selectors:

Selectors
*********

Linear
######

.. autoclass:: fastplotlib.graphics.selectors.LinearSelector
:members:
:inherited-members:

.. autoclass:: fastplotlib.graphics.selectors.LinearRegionSelector
:members:
:inherited-members:
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Welcome to fastplotlib's documentation!
Subplot <api/subplot>
Gridplot <api/gridplot>
Graphics <api/graphics>
Selectors <api/selectors>
Widgets <api/widgets>

Summary
Expand Down
1 change: 0 additions & 1 deletion fastplotlib/graphics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from .line import LineGraphic
from .scatter import ScatterGraphic
from .image import ImageGraphic, HeatmapGraphic
# from .heatmap import HeatmapGraphic
from .text import TextGraphic
from .line_collection import LineCollection, LineStack

Expand Down
6 changes: 1 addition & 5 deletions fastplotlib/graphics/features/_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,11 @@ def buffer(self) -> List[Texture]:
"""list of Texture buffer for the image data"""
return [img.geometry.grid for img in self._parent.world_object.children]

def update_gpu(self):
"""Update the GPU with the buffer"""
self._update_range(None)

def __getitem__(self, item):
return self._data[item]

def __call__(self, *args, **kwargs):
return self.buffer.data
return self._data

def __setitem__(self, key, value):
# make sure supported type, not float64 etc.
Expand Down
139 changes: 0 additions & 139 deletions fastplotlib/graphics/heatmap.py

This file was deleted.

149 changes: 147 additions & 2 deletions fastplotlib/graphics/image.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,162 @@
from typing import *
from math import ceil
from itertools import product
import weakref

import numpy as np
import pygfx

from ._base import Graphic, Interaction, PreviouslyModifiedData
from .selectors import LinearSelector, LinearRegionSelector
from .features import ImageCmapFeature, ImageDataFeature, HeatmapDataFeature, HeatmapCmapFeature
from .features._base import to_gpu_supported_dtype
from ..utils import quick_min_max


class ImageGraphic(Graphic, Interaction):
class _ImageHeatmapSelectorsMixin:
def add_linear_selector(self, selection: int = None, padding: float = 50, **kwargs) -> LinearSelector:
"""
Adds a linear selector.

Parameters
----------
selection: int
initial position of the selector

padding: float
pad the length of the selector

kwargs
passed to :class:`.LinearSelector`

Returns
-------
LinearSelector

"""

bounds_init, limits, size, origin, axis, end_points = self._get_linear_selector_init_args(padding, **kwargs)

if selection is None:
selection = limits[0]

if selection < limits[0] or selection > limits[1]:
raise ValueError(f"the passed selection: {selection} is beyond the limits: {limits}")

selector = LinearSelector(
selection=selection,
limits=limits,
end_points=end_points,
parent=weakref.proxy(self),
**kwargs
)

self._plot_area.add_graphic(selector, center=False)
selector.position.z = self.position.z + 1

return weakref.proxy(selector)

def add_linear_region_selector(self, padding: float = 100.0, **kwargs) -> LinearRegionSelector:
"""
Add a :class:`.LinearRegionSelector`. Selectors are just ``Graphic`` objects, so you can manage,
remove, or delete them from a plot area just like any other ``Graphic``.

Parameters
----------
padding: float, default 100.0
Extends the linear selector along the y-axis to make it easier to interact with.

kwargs
passed to ``LinearRegionSelector``

Returns
-------
LinearRegionSelector
linear selection graphic

"""

bounds_init, limits, size, origin, axis, end_points = self._get_linear_selector_init_args(padding, **kwargs)

# create selector
selector = LinearRegionSelector(
bounds=bounds_init,
limits=limits,
size=size,
origin=origin,
parent=weakref.proxy(self),
**kwargs
)

self._plot_area.add_graphic(selector, center=False)
# so that it is above this graphic
selector.position.set_z(self.position.z + 3)
selector.fill.material.color = (*selector.fill.material.color[:-1], 0.2)

# PlotArea manages this for garbage collection etc. just like all other Graphics
# so we should only work with a proxy on the user-end
return weakref.proxy(selector)

# TODO: this method is a bit of a mess, can refactor later
def _get_linear_selector_init_args(self, padding: float, **kwargs):
# computes initial bounds, limits, size and origin of linear selectors
data = self.data()

if "axis" in kwargs.keys():
axis = kwargs["axis"]
else:
axis = "x"

if axis == "x":
offset = self.position.x
# x limits, number of columns
limits = (offset, data.shape[1])

# size is number of rows + padding
# used by LinearRegionSelector but not LinearSelector
size = data.shape[0] + padding

# initial position of the selector
# center row
position_y = data.shape[0] / 2

# need y offset too for this
origin = (limits[0] - offset, position_y + self.position.y)

# endpoints of the data range
# used by linear selector but not linear region
# padding, n_rows + padding
end_points = (0 - padding, data.shape[0] + padding)
else:
offset = self.position.y
# y limits
limits = (offset, data.shape[0])

# width + padding
# used by LinearRegionSelector but not LinearSelector
size = data.shape[1] + padding

# initial position of the selector
position_x = data.shape[1] / 2

# need x offset too for this
origin = (position_x + self.position.x, limits[0] - offset)

# endpoints of the data range
# used by linear selector but not linear region
end_points = (0 - padding, data.shape[1] + padding)

# initial bounds are 20% of the limits range
# used by LinearRegionSelector but not LinearSelector
bounds_init = (limits[0], int(np.ptp(limits) * 0.2) + offset)

return bounds_init, limits, size, origin, axis, end_points

def _add_plot_area_hook(self, plot_area):
self._plot_area = plot_area


class ImageGraphic(Graphic, Interaction, _ImageHeatmapSelectorsMixin):
feature_events = (
"data",
"cmap",
Expand Down Expand Up @@ -178,7 +323,7 @@ def col_chunk_index(self, index: int):
self._col_chunk_index = index


class HeatmapGraphic(Graphic, Interaction):
class HeatmapGraphic(Graphic, Interaction, _ImageHeatmapSelectorsMixin):
feature_events = (
"data",
"cmap",
Expand Down
Loading