Repository: enthought/chaco

Issue:
changing TextPlot color & font
Hello,

I would like to change TextPlot color & font.

Initialization is ok, but when the color trait is changed for instance, the color is not changed in the display.

There is the same issue with the font trait.

Here's the CME.

```python
#! /usr/bin/env python3

import numpy as np

from chaco.api import ArrayPlotData, Plot
from enable.api import ComponentEditor
from traits.api import (
    Array,
    Color,
    Font,
    HasTraits,
    Instance,
    List
)
from traitsui.api import Item, UItem, View


class Data(HasTraits):

    data = Array
    labels = List
    color = Color
    font = Font
    plot = Instance(Plot)

    def _data_default(self):
        data = np.array([[0, 0], [0, 1], [1, 1], [1, 0]])
        return (data)

    def _labels_default(self):
        labels = ['A', 'B', 'C', 'D']
        return (labels)

    def _plot_default(self):
        self.plotdata = ArrayPlotData()
        self.plotdata.set_data('x', self.data[:, 0])
        self.plotdata.set_data('y', self.data[:, 1])
        self.plotdata.set_data('labels', self.labels)

        plot = Plot(self.plotdata)
        plot.range2d.set_bounds((-1, -1), (2, 2))
        plot.plot(("x", "y"),
                  type='scatter',
                  marker='dot',
                  color=self.color)
        plot.plot(("x", "y", "labels"),
                  type='text',
                  text_margin=4,
                  h_position='right',
                  text_offset=(4, 4),
                  text_color=self.color)

        return plot

    traits_view = View(
        UItem(
            "plot",
            editor=ComponentEditor(),
            resizable=True
        ),
        UItem('color',
              style='simple'),
        UItem('font'),
        resizable=True,
        buttons=["OK"],
        width=900,
        height=800,
    )

    def _color_changed(self):
        self.plot.plots['plot0'][0].color = self.color
        self.plot.plots['plot1'][0].text_color = self.color

    def _font_changed(self):
        name = self.font.family()
        size = self.font.pointSize()
        self.plot.plots['plot1'][0].text_font = '%s %d' % (name, size)


if __name__ == '__main__':
    viewer = Data(color=(255, 128, 64))
    viewer.configure_traits()
```

Thanks in advance for any help.

Regards

Debian 10 x86_64, Python 3.7.3, ETS source code from git repo



Discussion:
As a work-around, you can manually call `invalidate_and_redraw()` on the appropriate plot components in each of those change methods.

However the `TextPlot` should probably do that automatically.
This may just be a matter of adding `requires_redraw` metadata to the traits in `TextPlot` (see #595)
> As a work-around, you can manually call `invalidate_and_redraw()` on the appropriate plot components in each of those change methods.

I tried your hint, but unhappily, it does not fix the issue, nothing changes.

Resolving patch:
diff --git a/chaco/plots/text_plot.py b/chaco/plots/text_plot.py
--- a/chaco/plots/text_plot.py
+++ b/chaco/plots/text_plot.py
@@ -34,25 +34,25 @@ class TextPlot(BaseXYPlot):
     text = Instance(ArrayDataSource)
 
     #: The font of the tick labels.
-    text_font = KivaFont("sans-serif 10")
+    text_font = KivaFont("sans-serif 10", redraw=True)
 
     #: The color of the tick labels.
-    text_color = black_color_trait
+    text_color = black_color_trait(redraw=True)
 
     #: The rotation of the tick labels.
-    text_rotate_angle = Float(0)
+    text_rotate_angle = Float(0, redraw=True)
 
     #: The margin around the label.
-    text_margin = Int(2)
+    text_margin = Int(2, redraw=True)
 
     #: horizontal position of text relative to target point
-    h_position = Enum("center", "left", "right")
+    h_position = Enum("center", "left", "right", redraw=True)
 
     #: vertical position of text relative to target point
-    v_position = Enum("center", "top", "bottom")
+    v_position = Enum("center", "top", "bottom", redraw=True)
 
     #: offset of text relative to non-index direction in pixels
-    text_offset = Tuple(Float, Float)
+    text_offset = Tuple(Float, Float, redraw=True)
 
     # ------------------------------------------------------------------------
     # Private traits
@@ -173,6 +173,6 @@ def _invalidate(self, event):
         self._screen_cache_valid = False
         self._label_cache_valid = False
 
-    @observe("value.data_changed")
+    @observe("value.data_changed,+redraw")
     def _invalidate_labels(self, event):
         self._label_cache_valid = False


Test patch: