Provide feedback on task output#

In this chapter we will:

  • add a plot widget to ‘ClipDataOW’ that displays histogram values of ‘data’ in [0.0, 1.0]

  • update the plot widget when ewoks task output changes.

First let’s move the ‘MyWidget’ to the control area

From orange main area to control area#

diff --git a/src/orangecontrib/testtuto/ClipDataOW.py b/src/orangecontrib/testtuto/ClipDataOW.py
index 131e5da..606e74d 100644
--- a/src/orangecontrib/testtuto/ClipDataOW.py
+++ b/src/orangecontrib/testtuto/ClipDataOW.py
@@ -40,7 +40,7 @@ class ClipDataOW(
    id = "orange.widgets.my_project.ClipDataTask"
    description = "widget to clip data (numpy array) within a percentile range."
    want_main_area = True
-    want_control_area = False
+    want_control_area = True

    _ewoks_inputs_to_hide_from_orange = ("percentiles", )

@@ -48,7 +48,7 @@ class ClipDataOW(
        super().__init__(parent)

        self._myWidget = MyWidget(self)
-        self.mainArea.layout().addWidget(self._myWidget)
+        self.controlArea.layout().addWidget(self._myWidget)

        # set up percentiles
        self._myWidget.setPercentiles((10, 90))

Now the widget will looks like:

../../_images/myWidget_to_control_area.png

Adding a plot to the OrangeWidget#

 1class ClipDataOW(
 2    OWEwoksWidgetOneThread,
 3    ewokstaskclass=ClipDataTask,
 4):
 5    name = "rescale data"
 6    id = "orange.widgets.my_project.ClipDataTask"
 7    description = "widget to clip data (numpy array) within a percentile range."
 8    want_main_area = True
 9    want_control_area = True
10
11    _ewoks_inputs_to_hide_from_orange = ("percentiles", )
12
13    def __init__(self, parent=None):
14        super().__init__(parent)
15
16        self._plot = Plot1D(self)
17        self.mainArea.layout().addWidget(self._plot)
18        self._myWidget = MyWidget(self)
19        self.controlArea.layout().addWidget(self._myWidget)
20
21        # set up percentiles
22        self._myWidget.setPercentiles((10, 90))
23        self._percentileChanged()
24
25        # connect signal / slot
26        self._myWidget._minPercentiles.valueChanged.connect(self._percentileChanged)
27        self._myWidget._maxPercentiles.valueChanged.connect(self._percentileChanged)
28
29    def _percentileChanged(self):
30        self.set_dynamic_input("percentiles", self._myWidget.getPercentiles())
31        data = self.get_task_output_value("data")
32        if not is_missing_data(data):
33            self.execute_ewoks_task()
34
35    def task_output_changed(self):
36        data = self.get_task_output_value("data")
37        if is_missing_data(data):
38            self._plot.clear()
39        else:
40            # compute histogram
41            histogram, _ = numpy.histogram(data, bins=100, range=(0.0, 1.0))
42            self._plot.addCurve(x=numpy.linspace(0.0, 1.0, num=100), y=histogram, legend="histogram")
43        return super().task_output_changed()

Hint

  • l16-17: add a silx Plot1D widget and add it to the control area

  • l23: make sure the ‘percentiles’ is defined at start

  • l31-33: percentiles input will now be defined before data input (l23). So let’s make sure data is defined before processing the ewoks task.

  • l35-43: task_output_changed is called once the ewoks task has been processing:

    • If the task failed we clear the plot (l37-38)

    • Else we compute the histogram and display it.

Now your processing should looks like:

../../_images/output_feedback.gif

Hint

You can hide some input(s) you can also hide some output(s) using the _ewoks_outputs_to_hide_from_orange class attribute.

Further reading#

Going further: waiting for a user validation