From 430f0467e74b187bf50fd5c0c63f7f32d3c2e6ad Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Thu, 25 May 2023 23:50:19 -0400 Subject: [PATCH 1/2] feature docs --- fastplotlib/graphics/features/_base.py | 19 +++--- fastplotlib/graphics/features/_colors.py | 36 +++++++++++- fastplotlib/graphics/features/_present.py | 15 ++++- fastplotlib/graphics/features/_thickness.py | 13 ++++- fastplotlib/graphics/image.py | 26 +++++++-- fastplotlib/graphics/line.py | 16 ++++- fastplotlib/graphics/line_collection.py | 65 +++++++++++++++++++++ fastplotlib/graphics/scatter.py | 14 +++++ fastplotlib/graphics/selectors/_linear.py | 2 +- 9 files changed, 187 insertions(+), 19 deletions(-) diff --git a/fastplotlib/graphics/features/_base.py b/fastplotlib/graphics/features/_base.py index 57cd15a1d..82fa2847c 100644 --- a/fastplotlib/graphics/features/_base.py +++ b/fastplotlib/graphics/features/_base.py @@ -48,12 +48,14 @@ class FeatureEvent: type: str, example "colors" pick_info: dict in the form: - ============== ======================================================================= - index indices where feature data was changed, ``range`` object or List[int] - ============== ======================================================================= - world_object world object the feature belongs to - new_data the new data for this feature - ============== ======================================================================= + + ============== ============================================================================= + key value + ============== ============================================================================= + "index" indices where feature data was changed, ``range`` object or ``List[int]`` + "world_object" world object the feature belongs to + "new_data: the new data for this feature + ============== ============================================================================= """ def __init__(self, type: str, pick_info: dict): @@ -105,8 +107,8 @@ def add_event_handler(self, handler: callable): """ Add an event handler. All added event handlers are called when this feature changes. The `handler` can optionally accept ``FeatureEvent`` as the first and only argument. - The ``FeatureEvent`` only has two attributes, `type` which denotes the type of event - as a str in the form of "-changed", such as "color-changed". + The ``FeatureEvent`` only has two attributes, ``type`` which denotes the type of event + as a ``str`` in the form of "", such as "color". Parameters ---------- @@ -289,6 +291,7 @@ def _update_range(self, key): @property @abstractmethod def buffer(self) -> Union[Buffer, Texture]: + """Underlying buffer for this feature""" pass @property diff --git a/fastplotlib/graphics/features/_colors.py b/fastplotlib/graphics/features/_colors.py index 5ff82ca72..d607d6397 100644 --- a/fastplotlib/graphics/features/_colors.py +++ b/fastplotlib/graphics/features/_colors.py @@ -6,6 +6,22 @@ class ColorFeature(GraphicFeatureIndexable): + """ + Manages the color buffer for :class:`LineGraphic` or :class:`ScatterGraphic` + + **event pick info:** + + ==================== =============================== ========================================================================= + key type description + ==================== =============================== ========================================================================= + "index" ``numpy.ndarray`` or ``None`` changed indices in the buffer + "new_data" ``numpy.ndarray`` or ``None`` new buffer data at the changed indices + "collection-index" int the index of the graphic within the collection that triggered the event + "world_object" pygfx.WorldObject world object + ==================== =============================== ========================================================================= + + + """ @property def buffer(self): return self._parent.world_object.geometry.colors @@ -204,6 +220,8 @@ def _feature_changed(self, key, new_data): class CmapFeature(ColorFeature): """ Indexable colormap feature, mostly wraps colors and just provides a way to set colormaps. + + Same event pick info as :class:`ColorFeature` """ def __init__(self, parent, colors): super(ColorFeature, self).__init__(parent, colors) @@ -227,7 +245,19 @@ def __setitem__(self, key, value): class ImageCmapFeature(GraphicFeature): """ - Colormap for ImageGraphic + Colormap for :class:`ImageGraphic` + + **event pick info:** + + ================ =================== =============== + key type description + ================ =================== =============== + "index" ``None`` not used + "new_data" ``str`` colormap name + "world_object" pygfx.WorldObject world object + ================ =================== =============== + + """ def __init__(self, parent, cmap: str): cmap_texture_view = get_cmap_texture(cmap) @@ -257,7 +287,9 @@ def _feature_changed(self, key, new_data): class HeatmapCmapFeature(ImageCmapFeature): """ - Colormap for HeatmapGraphic + Colormap for :class:`HeatmapGraphic` + + Same event pick info as :class:`ImageCmapFeature` """ def _set(self, cmap_name: str): diff --git a/fastplotlib/graphics/features/_present.py b/fastplotlib/graphics/features/_present.py index 9bd439157..820c1d123 100644 --- a/fastplotlib/graphics/features/_present.py +++ b/fastplotlib/graphics/features/_present.py @@ -4,9 +4,20 @@ class PresentFeature(GraphicFeature): """ - Toggles if the object is present in the scene, different from visible \n + Toggles if the object is present in the scene, different from visible. Useful for computing bounding boxes from the Scene to only include graphics - that are present + that are present. + + **event pick info:** + + ==================== ======================== ========================================================================= + key type description + ==================== ======================== ========================================================================= + "index" ``None`` not used + "new_data" ``bool`` new data, ``True`` or ``False`` + "collection-index" int the index of the graphic within the collection that triggered the event + "world_object" pygfx.WorldObject world object + ==================== ======================== ======================================================================== """ def __init__(self, parent, present: bool = True, collection_index: int = False): self._scene = None diff --git a/fastplotlib/graphics/features/_thickness.py b/fastplotlib/graphics/features/_thickness.py index 5c7c3e00b..ce9c3cbc4 100644 --- a/fastplotlib/graphics/features/_thickness.py +++ b/fastplotlib/graphics/features/_thickness.py @@ -3,7 +3,18 @@ class ThicknessFeature(GraphicFeature): """ - Used by Line graphics for line material thickness + Used by Line graphics for line material thickness. + + **event pick info:** + + ===================== ======================== ========================================================================= + key type description + ==================== ======================== ========================================================================= + "index" ``None`` not used + "new_data" ``float`` new thickness value + "collection-index" int the index of the graphic within the collection that triggered the event + "world_object" pygfx.WorldObject world object + ==================== ======================== ======================================================================== """ def __init__(self, parent, thickness: float): self._scene = None diff --git a/fastplotlib/graphics/image.py b/fastplotlib/graphics/image.py index 5adfde338..a5318a330 100644 --- a/fastplotlib/graphics/image.py +++ b/fastplotlib/graphics/image.py @@ -226,6 +226,7 @@ def __init__( **present**: :class:`.PresentFeature` Control the presence of the Graphic in the scene + Examples -------- .. code-block:: python @@ -396,6 +397,20 @@ def __init__( kwargs: additional keyword arguments passed to Graphic + + Features + -------- + + **data**: :class:`.HeatmapDataFeature` + Manages the data buffer displayed in the HeatmapGraphic + + **cmap**: :class:`.HeatmapCmapFeature` + Manages the colormap + + **present**: :class:`.PresentFeature` + Control the presence of the Graphic in the scene + + Examples -------- .. code-block:: python @@ -403,10 +418,13 @@ def __init__( from fastplotlib import Plot # create a `Plot` instance plot = Plot() - # make some random 2D image data - data = np.random.rand(512, 512) - # plot the image data - plot.add_image(data=data) + + # make some random 2D heatmap data + data = np.random.rand(10_000, 8_000) + + # add a heatmap + plot.add_heatmap(data=data) + # show the plot plot.show() """ diff --git a/fastplotlib/graphics/line.py b/fastplotlib/graphics/line.py index dbfdfc40e..1d9db6d58 100644 --- a/fastplotlib/graphics/line.py +++ b/fastplotlib/graphics/line.py @@ -43,7 +43,7 @@ def __init__( thickness of the line colors: str, array, or iterable, default "w" - specify colors as a single human readable string, a single RGBA array, + specify colors as a single human-readable string, a single RGBA array, or an iterable of strings or RGBA arrays cmap: str, optional @@ -62,6 +62,20 @@ def __init__( kwargs passed to Graphic + Features + -------- + + **data**: :class:`.ImageDataFeature` + Manages the line [x, y, z] positions data buffer, allows regular and fancy indexing. + ex: ``scatter.data[:, 0] = 5```, ``scatter.data[xs > 5] = 3`` + + **colors**: :class:`.ColorFeature` + Manages the color buffer, allows regular and fancy indexing. + ex: ``scatter.data[:, 1] = 0.5``, ``scatter.colors[xs > 5] = "cyan"`` + + **present**: :class:`.PresentFeature` + Control the presence of the Graphic in the scene, set to ``True`` or ``False`` + """ self.data = PointsDataFeature(self, data, collection_index=collection_index) diff --git a/fastplotlib/graphics/line_collection.py b/fastplotlib/graphics/line_collection.py index be223677d..80a66e6bd 100644 --- a/fastplotlib/graphics/line_collection.py +++ b/fastplotlib/graphics/line_collection.py @@ -76,40 +76,76 @@ def __init__( kwargs passed to GraphicCollection + + Features + -------- + + Collections support the same features as the underlying graphic. You just have to slice the selection. + + .. code-block:: python + + # slice only the collection + line_collection[10:20].colors = "blue" + + # slice the collection and a feature + line_collection[20:30].colors[10:30] = "red" + + # the data feature also works like this + + See :class:`LineGraphic` details on the features. + + Examples -------- .. code-block:: python from fastplotlib import Plot from fastplotlib.graphics import LineCollection + # creating data for sine and cosine waves xs = np.linspace(-10, 10, 100) ys = np.sin(xs) + sine = np.dstack([xs, ys])[0] + ys = np.sin(xs) + 10 sine2 = np.dstack([xs, ys])[0] + ys = np.cos(xs) + 5 cosine = np.dstack([xs, ys])[0] + # creating plot plot = Plot() + # creating a line collection using the sine and cosine wave data line_collection = LineCollection(data=[sine, cosine, sine2], cmap=["Oranges", "Blues", "Reds"], thickness=20.0) + # add graphic to plot plot.add_graphic(line_collection) + # show plot plot.show() + # change the color of the sine wave to white line_collection[0].colors = "w" + # change certain color indexes of the cosine data to red line_collection[1].colors[0:15] = "r" + # toggle presence of sine2 and rescale graphics line_collection[2].present = False + plot.autoscale() + line_collection[2].present = True + plot.autoscale() + # can also do slicing line_collection[1:].colors[35:70] = "magenta" + """ + super(LineCollection, self).__init__(name) if not isinstance(z_position, float) and z_position is not None: @@ -481,30 +517,59 @@ def __init__( kwargs passed to LineCollection + + Features + -------- + + Collections support the same features as the underlying graphic. You just have to slice the selection. + + .. code-block:: python + + # slice only the collection + line_collection[10:20].colors = "blue" + + # slice the collection and a feature + line_collection[20:30].colors[10:30] = "red" + + # the data feature also works like this + + See :class:`LineGraphic` details on the features. + + Examples -------- .. code-block:: python from fastplotlib import Plot from fastplotlib.graphics import LineStack + # create plot plot = Plot() + # create line data xs = np.linspace(-10, 10, 100) ys = np.sin(xs) + sine = np.dstack([xs, ys])[0] + ys = np.sin(xs) cosine = np.dstack([xs, ys])[0] + # create line stack line_stack = LineStack(data=[sine, cosine], cmap=["Oranges", "Blues"], thickness=20.0, separation=5.0) + # add graphic to plot plot.add_graphic(line_stack) + # show plot plot.show() + # change the color of the sine wave to white line_stack[0].colors = "w" + # change certain color indexes of the cosine data to red line_stack[1].colors[0:15] = "r" + # more slicing line_stack[0].colors[35:70] = "magenta" diff --git a/fastplotlib/graphics/scatter.py b/fastplotlib/graphics/scatter.py index cfad8e7ce..5556b1de2 100644 --- a/fastplotlib/graphics/scatter.py +++ b/fastplotlib/graphics/scatter.py @@ -51,6 +51,20 @@ def __init__( kwargs passed to Graphic + Features + -------- + + **data**: :class:`.ImageDataFeature` + Manages the scatter [x, y, z] positions data buffer, allows regular and fancy indexing. + ex: ``scatter.data[:, 0] = 5```, ``scatter.data[xs > 5] = 3`` + + **colors**: :class:`.ColorFeature` + Manages the color buffer, allows regular and fancy indexing. + ex: ``scatter.data[:, 1] = 0.5``, ``scatter.colors[xs > 5] = "cyan"`` + + **present**: :class:`.PresentFeature` + Control the presence of the Graphic in the scene, set to ``True`` or ``False`` + """ self.data = PointsDataFeature(self, data) diff --git a/fastplotlib/graphics/selectors/_linear.py b/fastplotlib/graphics/selectors/_linear.py index 55b64b62f..8899f03b1 100644 --- a/fastplotlib/graphics/selectors/_linear.py +++ b/fastplotlib/graphics/selectors/_linear.py @@ -21,7 +21,7 @@ class LinearSelectionFeature(GraphicFeature): """ Manages the slider selection and callbacks - **pick info** + **event pick info** ================== ================================================================ key selection From c2e50ef3e46cd32dcd99c8d0eb6224c02eb36696 Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Fri, 26 May 2023 00:04:07 -0400 Subject: [PATCH 2/2] add all feature docs --- docs/source/api/graphic_features.rst | 70 +++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/docs/source/api/graphic_features.rst b/docs/source/api/graphic_features.rst index 449eaf297..2fe60ce24 100644 --- a/docs/source/api/graphic_features.rst +++ b/docs/source/api/graphic_features.rst @@ -1,5 +1,10 @@ -Features -******** +.. _api_graphic_features: + +Graphic Features +**************** + +Image +##### .. autoclass:: fastplotlib.graphics.features.ImageDataFeature :members: @@ -13,3 +18,64 @@ Features :exclude-members: __init__ :no-undoc-members: +Heatmap +####### + +.. autoclass:: fastplotlib.graphics.features.HeatmapDataFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +.. autoclass:: fastplotlib.graphics.features.HeatmapCmapFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +Line +#### + +.. autoclass:: fastplotlib.graphics.features.PositionsDataFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +.. autoclass:: fastplotlib.graphics.features.ColorsFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +.. autoclass:: fastplotlib.graphics.features.ThicknessFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +Scatter +####### + +.. autoclass:: fastplotlib.graphics.features.PositionsDataFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +.. autoclass:: fastplotlib.graphics.features.ColorsFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: + +Common +###### + +Features common to all graphics + +.. autoclass:: fastplotlib.graphics.features.PresentFeature + :members: + :inherited-members: + :exclude-members: __init__ + :no-undoc-members: