From ff49bea9c1fc8eec01a2a8241de64c9ca8df5287 Mon Sep 17 00:00:00 2001 From: Aaron Ayres Date: Mon, 5 Apr 2021 13:05:52 -0500 Subject: [PATCH 1/6] remove anytrait change handler in axis.py and replace with is_visual metadata --- chaco/axis.py | 102 +++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 64 deletions(-) diff --git a/chaco/axis.py b/chaco/axis.py index e321014e4..2dc8c92a8 100644 --- a/chaco/axis.py +++ b/chaco/axis.py @@ -33,6 +33,7 @@ Enum, Callable, ArrayOrNone, + observe ) # Local relative imports @@ -65,96 +66,102 @@ class PlotAxis(AbstractOverlay): mapper = Instance(AbstractMapper) #: Keep an origin for plots that aren't attached to a component - origin = Enum("bottom left", "top left", "bottom right", "top right") + origin = Enum( + "bottom left", + "top left", + "bottom right", + "top right", + is_visual=True + ) #: The text of the axis title. title = Trait("", Str, Unicode) # May want to add PlotLabel option #: The font of the title. - title_font = KivaFont("modern 12") + title_font = KivaFont("modern 12", is_visual=True) #: The spacing between the axis line and the title - title_spacing = Trait("auto", "auto", Float) + title_spacing = Trait("auto", "auto", Float, is_visual=True) #: The color of the title. - title_color = ColorTrait("black") + title_color = ColorTrait("black", is_visual=True) #: The angle of the title, in degrees, from horizontal line - title_angle = Float(0.0) + title_angle = Float(0.0, is_visual=True) #: The thickness (in pixels) of each tick. - tick_weight = Float(1.0) + tick_weight = Float(1.0, is_visual=True) #: The color of the ticks. - tick_color = ColorTrait("black") + tick_color = ColorTrait("black", is_visual=True) #: The font of the tick labels. - tick_label_font = KivaFont("modern 10") + tick_label_font = KivaFont("modern 10", is_visual=True) #: The color of the tick labels. - tick_label_color = ColorTrait("black") + tick_label_color = ColorTrait("black", is_visual=True) #: The rotation of the tick labels. - tick_label_rotate_angle = Float(0) + tick_label_rotate_angle = Float(0, is_visual=True) #: Whether to align to corners or edges (corner is better for 45 degree rotation) - tick_label_alignment = Enum("edge", "corner") + tick_label_alignment = Enum("edge", "corner", is_visual=True) #: The margin around the tick labels. - tick_label_margin = Int(2) + tick_label_margin = Int(2, is_visual=True) #: The distance of the tick label from the axis. - tick_label_offset = Float(8.0) + tick_label_offset = Float(8.0, is_visual=True) #: Whether the tick labels appear to the inside or the outside of the plot area - tick_label_position = Enum("outside", "inside") + tick_label_position = Enum("outside", "inside", is_visual=True) #: A callable that is passed the numerical value of each tick label and #: that returns a string. - tick_label_formatter = Callable(DEFAULT_TICK_FORMATTER) + tick_label_formatter = Callable(DEFAULT_TICK_FORMATTER, is_visual=True) #: The number of pixels by which the ticks extend into the plot area. - tick_in = Int(5) + tick_in = Int(5, is_visual=True) #: The number of pixels by which the ticks extend into the label area. - tick_out = Int(5) + tick_out = Int(5, is_visual=True) #: Are ticks visible at all? - tick_visible = Bool(True) + tick_visible = Bool(True, is_visual=True) #: The dataspace interval between ticks. - tick_interval = Trait("auto", "auto", Float) + tick_interval = Trait("auto", "auto", Float, is_visual=True) #: A callable that implements the AbstractTickGenerator interface. - tick_generator = Instance(AbstractTickGenerator) + tick_generator = Instance(AbstractTickGenerator, is_visual=True) #: The location of the axis relative to the plot. This determines where #: the axis title is located relative to the axis line. - orientation = Enum("top", "bottom", "left", "right") + orientation = Enum("top", "bottom", "left", "right", is_visual=True) #: Is the axis line visible? - axis_line_visible = Bool(True) + axis_line_visible = Bool(True, is_visual=True) #: The color of the axis line. - axis_line_color = ColorTrait("black") + axis_line_color = ColorTrait("black", is_visual=True) #: The line thickness (in pixels) of the axis line. - axis_line_weight = Float(1.0) + axis_line_weight = Float(1.0, is_visual=True) #: The dash style of the axis line. - axis_line_style = LineStyle("solid") + axis_line_style = LineStyle("solid", is_visual=True) #: A special version of the axis line that is more useful for geophysical #: plots. - small_haxis_style = Bool(False) + small_haxis_style = Bool(False, is_visual=True) #: Does the axis ensure that its end labels fall within its bounding area? - ensure_labels_bounded = Bool(False) + ensure_labels_bounded = Bool(False, is_visual=True) #: Does the axis prevent the ticks from being rendered outside its bounds? #: This flag is off by default because the standard axis *does* render ticks #: that encroach on the plot area. - ensure_ticks_bounded = Bool(False) + ensure_ticks_bounded = Bool(False, is_visual=True) #: Fired when the axis's range bounds change. updated = Event @@ -778,42 +785,9 @@ def _title_changed(self): if self.component: self.component.invalidate_draw() - def _anytrait_changed(self, name, old, new): - """For every trait that defines a visual attribute - we just call _invalidate() when a change is made. - """ - invalidate_traits = [ - "title_font", - "title_spacing", - "title_color", - "title_angle", - "tick_weight", - "tick_color", - "tick_label_font", - "tick_label_color", - "tick_label_rotate_angle", - "tick_label_alignment", - "tick_label_margin", - "tick_label_offset", - "tick_label_position", - "tick_label_formatter", - "tick_in", - "tick_out", - "tick_visible", - "tick_interval", - "tick_generator", - "orientation", - "origin", - "axis_line_visible", - "axis_line_color", - "axis_line_weight", - "axis_line_style", - "small_haxis_style", - "ensure_labels_bounded", - "ensure_ticks_bounded", - ] - if name in invalidate_traits: - self._invalidate() + @observe("+is_visual") + def _invalidate_on_changed_visual_attr(self, event): + self._invalidate() # ------------------------------------------------------------------------ # Initialization-related methods From d8427cd2d9da1f5910b425d1b6671a93140992d6 Mon Sep 17 00:00:00 2001 From: Aaron Ayres Date: Fri, 16 Apr 2021 14:03:47 -0700 Subject: [PATCH 2/6] convert anytrait changed handler in legend.py to use observe instead --- chaco/legend.py | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/chaco/legend.py b/chaco/legend.py index 3491b7557..361425933 100644 --- a/chaco/legend.py +++ b/chaco/legend.py @@ -19,6 +19,7 @@ Instance, Int, List, + observe, Str, ) @@ -487,29 +488,27 @@ def _composite_icon_renderer_default(self): return CompositeIconRenderer() # -- trait handlers -------------------------------------------------------- - def _anytrait_changed(self, name, old, new): - if name in ( - "font", - "border_padding", - "padding", - "line_spacing", - "icon_bounds", - "icon_spacing", - "labels", - "plots", - "plots_items", - "labels_items", - "border_width", - "align", - "position", - "position_items", - "bounds", - "bounds_items", - "label_at_top", - ): - self._layout_needed = True - if name == "color": - self.get_preferred_size() + @observe([ + "font", + "border_padding", + "padding", + "line_spacing", + "icon_bounds", + "icon_spacing", + "labels.items", + "plots.items", + "border_width", + "align", + "position.items", + "bounds.items", + "title_at_top", + ]) + def _udpate_layout_needed(self, event): + self._layout_needed = True + + @observe("color") + def _get_preferred_size_on_color_change(self, event): + self.get_preferred_size() def _plots_changed(self): """Invalidate the caches.""" From e8c75157cab38e70d8b24ea321d4b8398a04e6f8 Mon Sep 17 00:00:00 2001 From: Aaron Ayres Date: Fri, 16 Apr 2021 14:09:17 -0700 Subject: [PATCH 3/6] update scalar_image_function_inspector.py --- .../scalar_image_function_inspector.py | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/examples/demo/advanced/scalar_image_function_inspector.py b/examples/demo/advanced/scalar_image_function_inspector.py index 1d1a47e2f..4d2022941 100644 --- a/examples/demo/advanced/scalar_image_function_inspector.py +++ b/examples/demo/advanced/scalar_image_function_inspector.py @@ -90,15 +90,15 @@ class Model(HasTraits): buttons=["OK", "Cancel"], ) - function = Str("tanh(x**2+y)*cos(y)*jn(0,x+y*2)") + function = Str("tanh(x**2+y)*cos(y)*jn(0,x+y*2)", needs_compute=True) - npts_x = CInt(400) - npts_y = CInt(200) + npts_x = CInt(400, needs_compute=True) + npts_y = CInt(200, needs_compute=True) - min_x = CFloat(-2 * pi) - max_x = CFloat(2 * pi) - min_y = CFloat(-1.5 * pi) - max_y = CFloat(1.5 * pi) + min_x = CFloat(-2 * pi, needs_compute=True) + max_x = CFloat(2 * pi, needs_compute=True) + min_y = CFloat(-1.5 * pi, needs_compute=True) + max_y = CFloat(1.5 * pi, needs_compute=True) xs = Array ys = Array @@ -154,17 +154,9 @@ def compute_model(self): self.model_changed = True self._function = self.function - def _anytrait_changed(self, name, value): - if name in [ - "function", - "npts_x", - "npts_y", - "min_x", - "max_x", - "min_y", - "max_y", - ]: - self.compute_model() + @observe("+needs_compute") + def _compute_model_on_trait_update(self, event): + self.compute_model() class PlotUI(HasTraits): From 111955abdfa9999f7be82aa78f4d8c2776833f7f Mon Sep 17 00:00:00 2001 From: aaronayres35 <36972686+aaronayres35@users.noreply.github.com> Date: Tue, 11 May 2021 07:26:48 -0500 Subject: [PATCH 4/6] typo Co-authored-by: Poruri Sai Rahul --- chaco/legend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaco/legend.py b/chaco/legend.py index 361425933..3925a565e 100644 --- a/chaco/legend.py +++ b/chaco/legend.py @@ -503,7 +503,7 @@ def _composite_icon_renderer_default(self): "bounds.items", "title_at_top", ]) - def _udpate_layout_needed(self, event): + def _update_layout_needed(self, event): self._layout_needed = True @observe("color") From 5891415e4b433daf6d3955b86a8d18c66b1bda5c Mon Sep 17 00:00:00 2001 From: Aaron Ayres Date: Tue, 11 May 2021 07:54:17 -0500 Subject: [PATCH 5/6] suggested name changes --- chaco/legend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chaco/legend.py b/chaco/legend.py index 3925a565e..562b23ee3 100644 --- a/chaco/legend.py +++ b/chaco/legend.py @@ -503,11 +503,11 @@ def _composite_icon_renderer_default(self): "bounds.items", "title_at_top", ]) - def _update_layout_needed(self, event): + def _invalidate_existing_layout(self, event): self._layout_needed = True @observe("color") - def _get_preferred_size_on_color_change(self, event): + def _update_caches(self, event): self.get_preferred_size() def _plots_changed(self): From 6d84c7d59ffdbf212a6fadb62ccc039bc95aaf2b Mon Sep 17 00:00:00 2001 From: Aaron Ayres Date: Tue, 11 May 2021 10:52:07 -0500 Subject: [PATCH 6/6] dont use metadata --- chaco/axis.py | 93 ++++++++++++------- .../scalar_image_function_inspector.py | 18 ++-- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/chaco/axis.py b/chaco/axis.py index 2dc8c92a8..a0d149904 100644 --- a/chaco/axis.py +++ b/chaco/axis.py @@ -66,102 +66,96 @@ class PlotAxis(AbstractOverlay): mapper = Instance(AbstractMapper) #: Keep an origin for plots that aren't attached to a component - origin = Enum( - "bottom left", - "top left", - "bottom right", - "top right", - is_visual=True - ) + origin = Enum("bottom left", "top left", "bottom right", "top right") #: The text of the axis title. title = Trait("", Str, Unicode) # May want to add PlotLabel option #: The font of the title. - title_font = KivaFont("modern 12", is_visual=True) + title_font = KivaFont("modern 12") #: The spacing between the axis line and the title - title_spacing = Trait("auto", "auto", Float, is_visual=True) + title_spacing = Trait("auto", "auto", Float) #: The color of the title. - title_color = ColorTrait("black", is_visual=True) + title_color = ColorTrait("black") #: The angle of the title, in degrees, from horizontal line - title_angle = Float(0.0, is_visual=True) + title_angle = Float(0.0) #: The thickness (in pixels) of each tick. - tick_weight = Float(1.0, is_visual=True) + tick_weight = Float(1.0) #: The color of the ticks. - tick_color = ColorTrait("black", is_visual=True) + tick_color = ColorTrait("black") #: The font of the tick labels. - tick_label_font = KivaFont("modern 10", is_visual=True) + tick_label_font = KivaFont("modern 10") #: The color of the tick labels. - tick_label_color = ColorTrait("black", is_visual=True) + tick_label_color = ColorTrait("black") #: The rotation of the tick labels. - tick_label_rotate_angle = Float(0, is_visual=True) + tick_label_rotate_angle = Float(0) #: Whether to align to corners or edges (corner is better for 45 degree rotation) - tick_label_alignment = Enum("edge", "corner", is_visual=True) + tick_label_alignment = Enum("edge", "corner") #: The margin around the tick labels. - tick_label_margin = Int(2, is_visual=True) + tick_label_margin = Int(2) #: The distance of the tick label from the axis. - tick_label_offset = Float(8.0, is_visual=True) + tick_label_offset = Float(8.0) #: Whether the tick labels appear to the inside or the outside of the plot area - tick_label_position = Enum("outside", "inside", is_visual=True) + tick_label_position = Enum("outside", "inside") #: A callable that is passed the numerical value of each tick label and #: that returns a string. - tick_label_formatter = Callable(DEFAULT_TICK_FORMATTER, is_visual=True) + tick_label_formatter = Callable(DEFAULT_TICK_FORMATTER) #: The number of pixels by which the ticks extend into the plot area. - tick_in = Int(5, is_visual=True) + tick_in = Int(5) #: The number of pixels by which the ticks extend into the label area. - tick_out = Int(5, is_visual=True) + tick_out = Int(5) #: Are ticks visible at all? - tick_visible = Bool(True, is_visual=True) + tick_visible = Bool(True) #: The dataspace interval between ticks. - tick_interval = Trait("auto", "auto", Float, is_visual=True) + tick_interval = Trait("auto", "auto", Float) #: A callable that implements the AbstractTickGenerator interface. - tick_generator = Instance(AbstractTickGenerator, is_visual=True) + tick_generator = Instance(AbstractTickGenerator) #: The location of the axis relative to the plot. This determines where #: the axis title is located relative to the axis line. - orientation = Enum("top", "bottom", "left", "right", is_visual=True) + orientation = Enum("top", "bottom", "left", "right") #: Is the axis line visible? - axis_line_visible = Bool(True, is_visual=True) + axis_line_visible = Bool(True) #: The color of the axis line. - axis_line_color = ColorTrait("black", is_visual=True) + axis_line_color = ColorTrait("black") #: The line thickness (in pixels) of the axis line. - axis_line_weight = Float(1.0, is_visual=True) + axis_line_weight = Float(1.0) #: The dash style of the axis line. - axis_line_style = LineStyle("solid", is_visual=True) + axis_line_style = LineStyle("solid") #: A special version of the axis line that is more useful for geophysical #: plots. - small_haxis_style = Bool(False, is_visual=True) + small_haxis_style = Bool(False) #: Does the axis ensure that its end labels fall within its bounding area? - ensure_labels_bounded = Bool(False, is_visual=True) + ensure_labels_bounded = Bool(False) #: Does the axis prevent the ticks from being rendered outside its bounds? #: This flag is off by default because the standard axis *does* render ticks #: that encroach on the plot area. - ensure_ticks_bounded = Bool(False, is_visual=True) + ensure_ticks_bounded = Bool(False) #: Fired when the axis's range bounds change. updated = Event @@ -785,7 +779,36 @@ def _title_changed(self): if self.component: self.component.invalidate_draw() - @observe("+is_visual") + @observe([ + "title_font", + "title_spacing", + "title_color", + "title_angle", + "tick_weight", + "tick_color", + "tick_label_font", + "tick_label_color", + "tick_label_rotate_angle", + "tick_label_alignment", + "tick_label_margin", + "tick_label_offset", + "tick_label_position", + "tick_label_formatter", + "tick_in", + "tick_out", + "tick_visible", + "tick_interval", + "tick_generator", + "orientation", + "origin", + "axis_line_visible", + "axis_line_color", + "axis_line_weight", + "axis_line_style", + "small_haxis_style", + "ensure_labels_bounded", + "ensure_ticks_bounded", + ]) def _invalidate_on_changed_visual_attr(self, event): self._invalidate() diff --git a/examples/demo/advanced/scalar_image_function_inspector.py b/examples/demo/advanced/scalar_image_function_inspector.py index 4d2022941..9d4815e31 100644 --- a/examples/demo/advanced/scalar_image_function_inspector.py +++ b/examples/demo/advanced/scalar_image_function_inspector.py @@ -90,15 +90,15 @@ class Model(HasTraits): buttons=["OK", "Cancel"], ) - function = Str("tanh(x**2+y)*cos(y)*jn(0,x+y*2)", needs_compute=True) + function = Str("tanh(x**2+y)*cos(y)*jn(0,x+y*2)") - npts_x = CInt(400, needs_compute=True) - npts_y = CInt(200, needs_compute=True) + npts_x = CInt(400) + npts_y = CInt(200) - min_x = CFloat(-2 * pi, needs_compute=True) - max_x = CFloat(2 * pi, needs_compute=True) - min_y = CFloat(-1.5 * pi, needs_compute=True) - max_y = CFloat(1.5 * pi, needs_compute=True) + min_x = CFloat(-2 * pi) + max_x = CFloat(2 * pi) + min_y = CFloat(-1.5 * pi) + max_y = CFloat(1.5 * pi) xs = Array ys = Array @@ -154,7 +154,9 @@ def compute_model(self): self.model_changed = True self._function = self.function - @observe("+needs_compute") + @observe( + ["function", "npts_x", "npts_y", "min_x", "max_x", "min_y", "max_y"] + ) def _compute_model_on_trait_update(self, event): self.compute_model()