From 3a2c86dc97c36fb8054fe2b7bec90566aba85966 Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Mon, 24 Feb 2025 04:10:44 -0500 Subject: [PATCH 1/4] Graphic.add_text --- fastplotlib/graphics/_base.py | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/fastplotlib/graphics/_base.py b/fastplotlib/graphics/_base.py index a25bc7176..03af17826 100644 --- a/fastplotlib/graphics/_base.py +++ b/fastplotlib/graphics/_base.py @@ -361,6 +361,72 @@ def my_handler(event): feature = getattr(self, f"_{t}") feature.remove_event_handler(wrapper) + def add_text(self, text: str, location: str = "center", location_z: str = "front", **kwargs): + """ + Add a TextGraphic at one of the corners or center of this graphic. + + Note 1: + Note 2: Uses axis aligned bounding box to get corners, does not account for any rotation set on the graphic. + + Parameters + ---------- + text: str + text to display in the ``TextGraphic`` + + location: str, default "center" + one of "center", "top-left", "top-right", "bottom-right", or "bottom-left" + + location_z: str, default "front" + one of "front" or "back" + + spacing: float, default 2.0 + number of pixels from the corner of the graphic to the TextGraphic position, ignored if location = "center" + + kwargs + passed to ``TextGraphic`` + + Returns + ------- + TextGraphic + + """ + valid = ["center", "top-left", "top-right", "bottom-right", "bottom-left"] + if not isinstance(location, str): + raise TypeError("`location` must be of type ") + if location not in valid: + raise ValueError(f"`location` must be one of : {valid}, you have passed: {location}") + + if location == "center": + x, y, z, r = self.world_object.get_world_bounding_sphere() + + return self._plot_area.add_text(text, offset=(x, y, z), **kwargs) + + bbox = self.world_object.get_world_bounding_box() + + for i, axis in enumerate(["x", "y", "z"]): + if getattr(self._plot_area.camera.local, f"scale_{axis}") < 0: + # swap boundary values for this axis + bbox[0, i], bbox[1, i] = bbox[1, i], bbox[0, i] + print(f"flipped: {i}") + + [[x1, y1, z1], [x2, y2, z2]] = bbox + + # set (x, y, z) location of text based on user str + if "top" in location: + y = y2 + elif "bottom" in location: + y = y1 + if "left" in location: + x = x1 + elif "right" in location: + x = x2 + if location_z == "front": + z = z1 + elif location_z == "back": + z = z2 + + return self._plot_area.add_text(text, offset=(x, y, z), **kwargs) + def _fpl_add_plot_area_hook(self, plot_area): self._plot_area = plot_area From 8ec898d8192b76f240b1a354eb0a0b2fe1a2f89a Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Mon, 24 Feb 2025 04:14:07 -0500 Subject: [PATCH 2/4] comment, black --- fastplotlib/graphics/_base.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fastplotlib/graphics/_base.py b/fastplotlib/graphics/_base.py index 03af17826..8af8e6708 100644 --- a/fastplotlib/graphics/_base.py +++ b/fastplotlib/graphics/_base.py @@ -361,11 +361,13 @@ def my_handler(event): feature = getattr(self, f"_{t}") feature.remove_event_handler(wrapper) - def add_text(self, text: str, location: str = "center", location_z: str = "front", **kwargs): + def add_text( + self, text: str, location: str = "center", location_z: str = "front", **kwargs + ): """ Add a TextGraphic at one of the corners or center of this graphic. - Note 1: + Note 1: If an axis is flipped, location is relative to the rendered view not the location in world space Note 2: Uses axis aligned bounding box to get corners, does not account for any rotation set on the graphic. Parameters @@ -394,7 +396,9 @@ def add_text(self, text: str, location: str = "center", location_z: str = "front if not isinstance(location, str): raise TypeError("`location` must be of type ") if location not in valid: - raise ValueError(f"`location` must be one of : {valid}, you have passed: {location}") + raise ValueError( + f"`location` must be one of : {valid}, you have passed: {location}" + ) if location == "center": x, y, z, r = self.world_object.get_world_bounding_sphere() From c32a4bc66a918fed0fd3835d4f1fe3933510aa04 Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Mon, 24 Feb 2025 04:31:42 -0500 Subject: [PATCH 3/4] move if offset or data changes, WIP --- fastplotlib/graphics/_base.py | 92 +++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/fastplotlib/graphics/_base.py b/fastplotlib/graphics/_base.py index 8af8e6708..2081b292f 100644 --- a/fastplotlib/graphics/_base.py +++ b/fastplotlib/graphics/_base.py @@ -361,6 +361,47 @@ def my_handler(event): feature = getattr(self, f"_{t}") feature.remove_event_handler(wrapper) + def _get_corner(self, location: str, location_z) -> tuple[float, float, float]: + valid = ["center", "top-left", "top-right", "bottom-right", "bottom-left"] + if not isinstance(location, str): + raise TypeError("`location` must be of type ") + if location not in valid: + raise ValueError( + f"`location` must be one of : {valid}, you have passed: {location}" + ) + + if location == "center": + x, y, z, r = self.world_object.get_world_bounding_sphere() + + return (x, y, z) + + else: + bbox = self.world_object.get_world_bounding_box() + + for i, axis in enumerate(["x", "y", "z"]): + if getattr(self._plot_area.camera.local, f"scale_{axis}") < 0: + # swap boundary values for this axis + bbox[0, i], bbox[1, i] = bbox[1, i], bbox[0, i] + print(f"flipped: {i}") + + [[x1, y1, z1], [x2, y2, z2]] = bbox + + # set (x, y, z) location of text based on user str + if "top" in location: + y = y2 + elif "bottom" in location: + y = y1 + if "left" in location: + x = x1 + elif "right" in location: + x = x2 + if location_z == "front": + z = z1 + elif location_z == "back": + z = z2 + + return (x, y, z) + def add_text( self, text: str, location: str = "center", location_z: str = "front", **kwargs ): @@ -392,44 +433,23 @@ def add_text( TextGraphic """ - valid = ["center", "top-left", "top-right", "bottom-right", "bottom-left"] - if not isinstance(location, str): - raise TypeError("`location` must be of type ") - if location not in valid: - raise ValueError( - f"`location` must be one of : {valid}, you have passed: {location}" - ) + offset = self._get_corner(location, location_z) - if location == "center": - x, y, z, r = self.world_object.get_world_bounding_sphere() + def update_offset(ev): + new_offset = self._get_corner(*ev.graphic._location) + ev.graphic.offset = new_offset + + text_graphic = self._plot_area.add_text(text, offset=offset, metadata=(location, location_z), **kwargs) + text_graphic._location = (location, location_z) + + text_graphic.add_event_handler(update_offset, "offset") + + class_name = self.__class__.__name__ + + if "Line" in class_name or "Scatter" in class_name: + text_graphic.add_event_handler(update_offset, "data") - return self._plot_area.add_text(text, offset=(x, y, z), **kwargs) - - bbox = self.world_object.get_world_bounding_box() - - for i, axis in enumerate(["x", "y", "z"]): - if getattr(self._plot_area.camera.local, f"scale_{axis}") < 0: - # swap boundary values for this axis - bbox[0, i], bbox[1, i] = bbox[1, i], bbox[0, i] - print(f"flipped: {i}") - - [[x1, y1, z1], [x2, y2, z2]] = bbox - - # set (x, y, z) location of text based on user str - if "top" in location: - y = y2 - elif "bottom" in location: - y = y1 - if "left" in location: - x = x1 - elif "right" in location: - x = x2 - if location_z == "front": - z = z1 - elif location_z == "back": - z = z2 - - return self._plot_area.add_text(text, offset=(x, y, z), **kwargs) + return text_graphic def _fpl_add_plot_area_hook(self, plot_area): self._plot_area = plot_area From 9722aacb9ccd136db653a195520e0e43b9c171c1 Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Mon, 24 Feb 2025 04:43:29 -0500 Subject: [PATCH 4/4] text moves if graphic offset or data change --- fastplotlib/graphics/_base.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/fastplotlib/graphics/_base.py b/fastplotlib/graphics/_base.py index 2081b292f..c075ad048 100644 --- a/fastplotlib/graphics/_base.py +++ b/fastplotlib/graphics/_base.py @@ -49,6 +49,12 @@ ] +def _update_text_offset(parent, tg, ev): + # helper function + new_offset = parent._fpl_get_corner(*tg._location) + tg.offset = new_offset + + class Graphic: _features: set[str] = {} @@ -361,7 +367,8 @@ def my_handler(event): feature = getattr(self, f"_{t}") feature.remove_event_handler(wrapper) - def _get_corner(self, location: str, location_z) -> tuple[float, float, float]: + def _fpl_get_corner(self, location: str, location_z) -> tuple[float, float, float]: + """Get the (x, y, z) corner of a graphic relative to the rendered view""" valid = ["center", "top-left", "top-right", "bottom-right", "bottom-left"] if not isinstance(location, str): raise TypeError("`location` must be of type ") @@ -382,7 +389,6 @@ def _get_corner(self, location: str, location_z) -> tuple[float, float, float]: if getattr(self._plot_area.camera.local, f"scale_{axis}") < 0: # swap boundary values for this axis bbox[0, i], bbox[1, i] = bbox[1, i], bbox[0, i] - print(f"flipped: {i}") [[x1, y1, z1], [x2, y2, z2]] = bbox @@ -433,21 +439,19 @@ def add_text( TextGraphic """ - offset = self._get_corner(location, location_z) - - def update_offset(ev): - new_offset = self._get_corner(*ev.graphic._location) - ev.graphic.offset = new_offset + offset = self._fpl_get_corner(location, location_z) text_graphic = self._plot_area.add_text(text, offset=offset, metadata=(location, location_z), **kwargs) text_graphic._location = (location, location_z) - text_graphic.add_event_handler(update_offset, "offset") + events = ["offset"] class_name = self.__class__.__name__ if "Line" in class_name or "Scatter" in class_name: - text_graphic.add_event_handler(update_offset, "data") + events.append("data") + + self.add_event_handler(partial(_update_text_offset, self, text_graphic), *events) return text_graphic pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy