From 74325c1ff405acf89ed456a10c396166b88458b1 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Tue, 22 Oct 2024 20:35:12 -0400 Subject: [PATCH 1/5] add vertex, edge, and fill color properties --- .../graphics/selectors/_base_selector.py | 35 +++++++++++++++++++ fastplotlib/graphics/selectors/_linear.py | 3 ++ .../graphics/selectors/_linear_region.py | 10 +++--- fastplotlib/graphics/selectors/_rectangle.py | 30 +++++++++------- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/fastplotlib/graphics/selectors/_base_selector.py b/fastplotlib/graphics/selectors/_base_selector.py index 30643bbe4..597124b20 100644 --- a/fastplotlib/graphics/selectors/_base_selector.py +++ b/fastplotlib/graphics/selectors/_base_selector.py @@ -40,6 +40,41 @@ class BaseSelector(Graphic): def axis(self) -> str: return self._axis + @property + def fill_color(self) -> str | Sequence[float] | None: + return self._fill_color + + @fill_color.setter + def fill_color(self, color: str | Sequence[float]): + for fill in self._fill: + fill.material.color = color + self._original_colors[fill] = color + self._fill_color = color + + @property + def vertex_color(self) -> str | Sequence[float] | None: + return self._vertex_color + + @vertex_color.setter + def vertex_color(self, color: str | Sequence[float]): + for vertex in self._vertices: + vertex.material.color = color + vertex.material.edge_color = color + self._original_colors[vertex] = color + self._vertex_color = color + + + @property + def edge_color(self) -> str | Sequence[float] | None: + return self._edge_color + + @edge_color.setter + def edge_color(self, color: str | Sequence[float]): + for edge in self._edges: + edge.material.color = color + self._original_colors[edge] = color + self._edge_color = color + def __init__( self, edges: Tuple[Line, ...] = None, diff --git a/fastplotlib/graphics/selectors/_linear.py b/fastplotlib/graphics/selectors/_linear.py index dfe7aadab..46088ee04 100644 --- a/fastplotlib/graphics/selectors/_linear.py +++ b/fastplotlib/graphics/selectors/_linear.py @@ -99,6 +99,9 @@ def __init__( name of linear selector """ + self._fill_color = None + self._edge_color = None + self._vertex_color = None if len(limits) != 2: raise ValueError("limits must be a tuple of 2 integers, i.e. (int, int)") diff --git a/fastplotlib/graphics/selectors/_linear_region.py b/fastplotlib/graphics/selectors/_linear_region.py index db7788d00..a973c92e8 100644 --- a/fastplotlib/graphics/selectors/_linear_region.py +++ b/fastplotlib/graphics/selectors/_linear_region.py @@ -114,6 +114,8 @@ def __init__( name of this selector graphic """ + self._edge_color = edge_color + self._fill_color = fill_color # lots of very close to zero values etc. so round them, otherwise things get weird if not len(selection) == 2: @@ -134,13 +136,13 @@ def __init__( if axis == "x": mesh = pygfx.Mesh( pygfx.box_geometry(1, size, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(fill_color), pick_write=True), + pygfx.MeshBasicMaterial(color=pygfx.Color(self.fill_color), pick_write=True), ) elif axis == "y": mesh = pygfx.Mesh( pygfx.box_geometry(size, 1, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(fill_color), pick_write=True), + pygfx.MeshBasicMaterial(color=pygfx.Color(self.fill_color), pick_write=True), ) else: raise ValueError("`axis` must be one of 'x' or 'y'") @@ -179,7 +181,7 @@ def __init__( positions=init_line_data.copy() ), # copy so the line buffer is isolated pygfx.LineMaterial( - thickness=edge_thickness, color=edge_color, pick_write=True + thickness=edge_thickness, color=self.edge_color, pick_write=True ), ) line1 = pygfx.Line( @@ -187,7 +189,7 @@ def __init__( positions=init_line_data.copy() ), # copy so the line buffer is isolated pygfx.LineMaterial( - thickness=edge_thickness, color=edge_color, pick_write=True + thickness=edge_thickness, color=self.edge_color, pick_write=True ), ) diff --git a/fastplotlib/graphics/selectors/_rectangle.py b/fastplotlib/graphics/selectors/_rectangle.py index 356b437d7..e76e28209 100644 --- a/fastplotlib/graphics/selectors/_rectangle.py +++ b/fastplotlib/graphics/selectors/_rectangle.py @@ -117,6 +117,10 @@ def __init__( xmin, xmax, ymin, ymax = selection + self._fill_color = fill_color + self._edge_color = edge_color + self._vertex_color = vertex_color + width = xmax - xmin height = ymax - ymin @@ -125,7 +129,7 @@ def __init__( self.fill = pygfx.Mesh( pygfx.box_geometry(width, height, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(fill_color), pick_write=True), + pygfx.MeshBasicMaterial(color=pygfx.Color(self.fill_color), pick_write=True), ) self.fill.world.position = (0, 0, -2) @@ -142,7 +146,7 @@ def __init__( left_line = pygfx.Line( pygfx.Geometry(positions=left_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) # position data for the right edge line @@ -155,7 +159,7 @@ def __init__( right_line = pygfx.Line( pygfx.Geometry(positions=right_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) # position data for the left edge line @@ -168,7 +172,7 @@ def __init__( bottom_line = pygfx.Line( pygfx.Geometry(positions=bottom_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) # position data for the right edge line @@ -181,7 +185,7 @@ def __init__( top_line = pygfx.Line( pygfx.Geometry(positions=top_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) self.edges: Tuple[pygfx.Line, pygfx.Line, pygfx.Line, pygfx.Line] = ( @@ -207,9 +211,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) @@ -218,9 +222,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) @@ -231,9 +235,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) @@ -244,9 +248,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) From e8c941ef53f644c603f5f62f10e821967db30598 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Tue, 22 Oct 2024 20:40:55 -0400 Subject: [PATCH 2/5] update api docs --- docs/source/api/selectors/LinearRegionSelector.rst | 3 +++ docs/source/api/selectors/LinearSelector.rst | 3 +++ docs/source/api/selectors/RectangleSelector.rst | 3 +++ 3 files changed, 9 insertions(+) diff --git a/docs/source/api/selectors/LinearRegionSelector.rst b/docs/source/api/selectors/LinearRegionSelector.rst index 9637dd8e1..6c8d2eefc 100644 --- a/docs/source/api/selectors/LinearRegionSelector.rst +++ b/docs/source/api/selectors/LinearRegionSelector.rst @@ -24,7 +24,9 @@ Properties LinearRegionSelector.axis LinearRegionSelector.block_events LinearRegionSelector.deleted + LinearRegionSelector.edge_color LinearRegionSelector.event_handlers + LinearRegionSelector.fill_color LinearRegionSelector.limits LinearRegionSelector.name LinearRegionSelector.offset @@ -33,6 +35,7 @@ Properties LinearRegionSelector.rotation LinearRegionSelector.selection LinearRegionSelector.supported_events + LinearRegionSelector.vertex_color LinearRegionSelector.visible LinearRegionSelector.world_object diff --git a/docs/source/api/selectors/LinearSelector.rst b/docs/source/api/selectors/LinearSelector.rst index c514f982c..b82e3c1df 100644 --- a/docs/source/api/selectors/LinearSelector.rst +++ b/docs/source/api/selectors/LinearSelector.rst @@ -24,7 +24,9 @@ Properties LinearSelector.axis LinearSelector.block_events LinearSelector.deleted + LinearSelector.edge_color LinearSelector.event_handlers + LinearSelector.fill_color LinearSelector.limits LinearSelector.name LinearSelector.offset @@ -33,6 +35,7 @@ Properties LinearSelector.rotation LinearSelector.selection LinearSelector.supported_events + LinearSelector.vertex_color LinearSelector.visible LinearSelector.world_object diff --git a/docs/source/api/selectors/RectangleSelector.rst b/docs/source/api/selectors/RectangleSelector.rst index 930e12c67..81c9afd66 100644 --- a/docs/source/api/selectors/RectangleSelector.rst +++ b/docs/source/api/selectors/RectangleSelector.rst @@ -24,7 +24,9 @@ Properties RectangleSelector.axis RectangleSelector.block_events RectangleSelector.deleted + RectangleSelector.edge_color RectangleSelector.event_handlers + RectangleSelector.fill_color RectangleSelector.limits RectangleSelector.name RectangleSelector.offset @@ -33,6 +35,7 @@ Properties RectangleSelector.rotation RectangleSelector.selection RectangleSelector.supported_events + RectangleSelector.vertex_color RectangleSelector.visible RectangleSelector.world_object From 6f84ac4f82fa5333d5c9ece6dbc2f60ab378c383 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Tue, 22 Oct 2024 20:45:40 -0400 Subject: [PATCH 3/5] lint --- fastplotlib/graphics/selectors/_base_selector.py | 1 - fastplotlib/graphics/selectors/_linear_region.py | 8 ++++++-- fastplotlib/graphics/selectors/_rectangle.py | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fastplotlib/graphics/selectors/_base_selector.py b/fastplotlib/graphics/selectors/_base_selector.py index 597124b20..7badeec5b 100644 --- a/fastplotlib/graphics/selectors/_base_selector.py +++ b/fastplotlib/graphics/selectors/_base_selector.py @@ -63,7 +63,6 @@ def vertex_color(self, color: str | Sequence[float]): self._original_colors[vertex] = color self._vertex_color = color - @property def edge_color(self) -> str | Sequence[float] | None: return self._edge_color diff --git a/fastplotlib/graphics/selectors/_linear_region.py b/fastplotlib/graphics/selectors/_linear_region.py index a973c92e8..e0e5b7309 100644 --- a/fastplotlib/graphics/selectors/_linear_region.py +++ b/fastplotlib/graphics/selectors/_linear_region.py @@ -136,13 +136,17 @@ def __init__( if axis == "x": mesh = pygfx.Mesh( pygfx.box_geometry(1, size, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(self.fill_color), pick_write=True), + pygfx.MeshBasicMaterial( + color=pygfx.Color(self.fill_color), pick_write=True + ), ) elif axis == "y": mesh = pygfx.Mesh( pygfx.box_geometry(size, 1, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(self.fill_color), pick_write=True), + pygfx.MeshBasicMaterial( + color=pygfx.Color(self.fill_color), pick_write=True + ), ) else: raise ValueError("`axis` must be one of 'x' or 'y'") diff --git a/fastplotlib/graphics/selectors/_rectangle.py b/fastplotlib/graphics/selectors/_rectangle.py index e76e28209..8b83ebcbe 100644 --- a/fastplotlib/graphics/selectors/_rectangle.py +++ b/fastplotlib/graphics/selectors/_rectangle.py @@ -129,7 +129,9 @@ def __init__( self.fill = pygfx.Mesh( pygfx.box_geometry(width, height, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(self.fill_color), pick_write=True), + pygfx.MeshBasicMaterial( + color=pygfx.Color(self.fill_color), pick_write=True + ), ) self.fill.world.position = (0, 0, -2) From 92856a31bbfb8f3b143f81f384144ddca9231ac3 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Wed, 23 Oct 2024 12:16:24 -0400 Subject: [PATCH 4/5] requested changes --- fastplotlib/graphics/selectors/_base_selector.py | 10 +++++++--- fastplotlib/graphics/selectors/_linear.py | 8 ++++---- fastplotlib/graphics/selectors/_linear_region.py | 4 ++-- fastplotlib/graphics/selectors/_rectangle.py | 6 +++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/fastplotlib/graphics/selectors/_base_selector.py b/fastplotlib/graphics/selectors/_base_selector.py index 7badeec5b..7e14001d7 100644 --- a/fastplotlib/graphics/selectors/_base_selector.py +++ b/fastplotlib/graphics/selectors/_base_selector.py @@ -3,6 +3,7 @@ from functools import partial import numpy as np +import pygfx from pygfx import WorldObject, Line, Mesh, Points @@ -41,22 +42,24 @@ def axis(self) -> str: return self._axis @property - def fill_color(self) -> str | Sequence[float] | None: + def fill_color(self) -> pygfx.Color: return self._fill_color @fill_color.setter def fill_color(self, color: str | Sequence[float]): + color = pygfx.Color(color) for fill in self._fill: fill.material.color = color self._original_colors[fill] = color self._fill_color = color @property - def vertex_color(self) -> str | Sequence[float] | None: + def vertex_color(self) -> pygfx.Color: return self._vertex_color @vertex_color.setter def vertex_color(self, color: str | Sequence[float]): + color = pygfx.Color(color) for vertex in self._vertices: vertex.material.color = color vertex.material.edge_color = color @@ -64,11 +67,12 @@ def vertex_color(self, color: str | Sequence[float]): self._vertex_color = color @property - def edge_color(self) -> str | Sequence[float] | None: + def edge_color(self) -> pygfx.Color: return self._edge_color @edge_color.setter def edge_color(self, color: str | Sequence[float]): + color = pygfx.Color(color) for edge in self._edges: edge.material.color = color self._original_colors[edge] = color diff --git a/fastplotlib/graphics/selectors/_linear.py b/fastplotlib/graphics/selectors/_linear.py index 46088ee04..590b9eb00 100644 --- a/fastplotlib/graphics/selectors/_linear.py +++ b/fastplotlib/graphics/selectors/_linear.py @@ -56,7 +56,7 @@ def __init__( center: float, axis: str = "x", parent: Graphic = None, - color: str | Sequence[float] | np.ndarray = "w", + edge_color: str | Sequence[float] | np.ndarray = "w", thickness: float = 2.5, arrow_keys_modifier: str = "Shift", name: str = None, @@ -92,7 +92,7 @@ def __init__( thickness: float, default 2.5 thickness of the selector - color: str | tuple | np.ndarray, default "w" + edge_color: str | tuple | np.ndarray, default "w" color of the selector name: str, optional @@ -100,7 +100,7 @@ def __init__( """ self._fill_color = None - self._edge_color = None + self._edge_color = pygfx.Color(edge_color) self._vertex_color = None if len(limits) != 2: @@ -137,7 +137,7 @@ def __init__( line_inner = pygfx.Line( # self.data.feature_data because data is a Buffer geometry=pygfx.Geometry(positions=line_data), - material=material(thickness=thickness, color=color, pick_write=True), + material=material(thickness=thickness, color=edge_color, pick_write=True), ) self.line_outer = pygfx.Line( diff --git a/fastplotlib/graphics/selectors/_linear_region.py b/fastplotlib/graphics/selectors/_linear_region.py index e0e5b7309..60c6fd9cc 100644 --- a/fastplotlib/graphics/selectors/_linear_region.py +++ b/fastplotlib/graphics/selectors/_linear_region.py @@ -114,8 +114,8 @@ def __init__( name of this selector graphic """ - self._edge_color = edge_color - self._fill_color = fill_color + self._edge_color = pygfx.Color(edge_color) + self._fill_color = pygfx.Color(fill_color) # lots of very close to zero values etc. so round them, otherwise things get weird if not len(selection) == 2: diff --git a/fastplotlib/graphics/selectors/_rectangle.py b/fastplotlib/graphics/selectors/_rectangle.py index 8b83ebcbe..51c3209b1 100644 --- a/fastplotlib/graphics/selectors/_rectangle.py +++ b/fastplotlib/graphics/selectors/_rectangle.py @@ -117,9 +117,9 @@ def __init__( xmin, xmax, ymin, ymax = selection - self._fill_color = fill_color - self._edge_color = edge_color - self._vertex_color = vertex_color + self._fill_color = pygfx.Color(fill_color) + self._edge_color = pygfx.Color(edge_color) + self._vertex_color = pygfx.Color(vertex_color) width = xmax - xmin height = ymax - ymin From a993d8e509b7475d069ffd815395e4c537f1f3f1 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Thu, 24 Oct 2024 09:20:35 -0400 Subject: [PATCH 5/5] add doc strings, fix linear selector --- .../graphics/selectors/_base_selector.py | 27 +++++++++++++++++++ fastplotlib/graphics/selectors/_linear.py | 21 +++++++++++++++ .../graphics/selectors/_linear_region.py | 1 + 3 files changed, 49 insertions(+) diff --git a/fastplotlib/graphics/selectors/_base_selector.py b/fastplotlib/graphics/selectors/_base_selector.py index 7e14001d7..5158a9239 100644 --- a/fastplotlib/graphics/selectors/_base_selector.py +++ b/fastplotlib/graphics/selectors/_base_selector.py @@ -43,10 +43,19 @@ def axis(self) -> str: @property def fill_color(self) -> pygfx.Color: + """Returns the fill color of the selector, ``None`` if selector has no fill.""" return self._fill_color @fill_color.setter def fill_color(self, color: str | Sequence[float]): + """ + Set the fill color of the selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ color = pygfx.Color(color) for fill in self._fill: fill.material.color = color @@ -55,10 +64,19 @@ def fill_color(self, color: str | Sequence[float]): @property def vertex_color(self) -> pygfx.Color: + """Returns the vertex color of the selector, ``None`` if selector has no vertices.""" return self._vertex_color @vertex_color.setter def vertex_color(self, color: str | Sequence[float]): + """ + Set the vertex color of the selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ color = pygfx.Color(color) for vertex in self._vertices: vertex.material.color = color @@ -68,10 +86,19 @@ def vertex_color(self, color: str | Sequence[float]): @property def edge_color(self) -> pygfx.Color: + """Returns the edge color of the selector""" return self._edge_color @edge_color.setter def edge_color(self, color: str | Sequence[float]): + """ + Set the edge color of the selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ color = pygfx.Color(color) for edge in self._edges: edge.material.color = color diff --git a/fastplotlib/graphics/selectors/_linear.py b/fastplotlib/graphics/selectors/_linear.py index 590b9eb00..fe57036a3 100644 --- a/fastplotlib/graphics/selectors/_linear.py +++ b/fastplotlib/graphics/selectors/_linear.py @@ -47,6 +47,27 @@ def limits(self, values: tuple[float, float]): ) # if values are close to zero things get weird so round them self.selection._limits = self._limits + @property + def edge_color(self) -> pygfx.Color: + """Returns the color of the linear selector.""" + return self._edge_color + + @edge_color.setter + def edge_color(self, color: str | Sequence[float]): + """ + Set the color of the linear selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ + color = pygfx.Color(color) + # only want to change inner line color + self._edges[0].material.color = color + self._original_colors[self._edges[0]] = color + self._edge_color = color + # TODO: make `selection` arg in graphics data space not world space def __init__( self, diff --git a/fastplotlib/graphics/selectors/_linear_region.py b/fastplotlib/graphics/selectors/_linear_region.py index 60c6fd9cc..c1e6095f8 100644 --- a/fastplotlib/graphics/selectors/_linear_region.py +++ b/fastplotlib/graphics/selectors/_linear_region.py @@ -116,6 +116,7 @@ def __init__( """ self._edge_color = pygfx.Color(edge_color) self._fill_color = pygfx.Color(fill_color) + self._vertex_color = None # lots of very close to zero values etc. so round them, otherwise things get weird if not len(selection) == 2: