Repository: biolab/orange3

Issue:
Scatter Plot: show regression coefficient in black
<!-- 
Thanks for taking the time to report a bug!
If you're raising an issue about an add-on (i.e., installed via Options > Add-ons), raise an issue in the relevant add-on's issue tracker instead. See: https://github.com/biolab?q=orange3
To fix the bug, we need to be able to reproduce it. Please answer the following questions to the best of your ability.
-->


**What's wrong?**
<!-- Be specific, clear, and concise. Include screenshots if relevant. -->
<!-- If you're getting an error message, copy it, and enclose it with three backticks (```). -->
When using "Show color regions" and "Show regression line" with multilabel target, the green coefficient is hardly visible. Green is not the best color for displaying text.

Proposed solution: display all regression coefficients in black. As they stick to their own regression line, it should be clear enough which coefficient belongs to which line. I think.

<img width="895" alt="Screen Shot 2021-08-27 at 12 30 33" src="https://user-images.githubusercontent.com/12524972/131114182-29eddb02-013c-4a6d-bb71-eb9057b44ada.png">



**How can we reproduce the problem?** 
<!-- Upload a zip with the .ows file and data. -->
<!-- Describe the steps (open this widget, click there, then add this...) -->
File - Scatter Plot. Tick "Show color regions" and "Show regression line".



**What's your environment?**
<!-- To find your Orange version, see "Help → About → Version" or `Orange.version.full_version` in code -->
- Operating system: OSX
- Orange version: 3.30.dev
- How you installed Orange: git



Discussion:

Resolving patch:
diff --git a/Orange/widgets/visualize/owscatterplot.py b/Orange/widgets/visualize/owscatterplot.py
--- a/Orange/widgets/visualize/owscatterplot.py
+++ b/Orange/widgets/visualize/owscatterplot.py
@@ -225,6 +225,17 @@ def _add_line(self, x, y, color, width):
         self.plot_widget.addItem(line)
         self.reg_line_items.append(line)
 
+    def _update_reg_line_label_colors(self):
+        for line in self.reg_line_items:
+            if hasattr(line, "label"):
+                color = 0.0 if self.class_density \
+                    else line.pen.color().darker(175)
+                line.label.setColor(color)
+
+    def update_density(self):
+        super().update_density()
+        self._update_reg_line_label_colors()
+
     def update_regression_line(self):
         for line in self.reg_line_items:
             self.plot_widget.removeItem(line)
@@ -235,7 +246,7 @@ def update_regression_line(self):
         x, y = self.master.get_coordinates_data()
         if x is None:
             return
-        self._add_line(x, y, QColor("#505050"), width=2)
+        self._add_line(x, y, QColor("#505050"), width=3)
         if self.master.is_continuous_color() or self.palette is None:
             return
         c_data = self.master.get_color_data()
@@ -245,7 +256,10 @@ def update_regression_line(self):
         for val in range(c_data.max() + 1):
             mask = c_data == val
             if mask.sum() > 1:
-                self._add_line(x[mask], y[mask], self.palette[val], width=2)
+                self._add_line(x[mask], y[mask],
+                               self.palette[val].darker(135),
+                               width=3)
+        self._update_reg_line_label_colors()
 
 
 class OWScatterPlot(OWDataProjectionWidget):


Test patch:
diff --git a/Orange/widgets/visualize/tests/test_owscatterplot.py b/Orange/widgets/visualize/tests/test_owscatterplot.py
--- a/Orange/widgets/visualize/tests/test_owscatterplot.py
+++ b/Orange/widgets/visualize/tests/test_owscatterplot.py
@@ -847,13 +847,13 @@ def test_regression_line_coeffs(self):
         self.assertEqual(line1.pos().x(), 0)
         self.assertEqual(line1.pos().y(), 0)
         self.assertEqual(line1.angle, 45)
-        self.assertEqual(line1.pen.color().getRgb(), graph.palette[0].getRgb())
+        self.assertEqual(line1.pen.color().hue(), graph.palette[0].hue())
 
         line2 = graph.reg_line_items[2]
         self.assertEqual(line2.pos().x(), 0)
         self.assertEqual(line2.pos().y(), 1)
         self.assertAlmostEqual(line2.angle, np.degrees(np.arctan2(2, 1)))
-        self.assertEqual(line2.pen.color().getRgb(), graph.palette[1].getRgb())
+        self.assertEqual(line2.pen.color().hue(), graph.palette[1].hue())
 
         graph.orthonormal_regression = True
         graph.update_regression_line()
@@ -862,13 +862,13 @@ def test_regression_line_coeffs(self):
         self.assertEqual(line1.pos().x(), 0)
         self.assertAlmostEqual(line1.pos().y(), -0.6180339887498949)
         self.assertAlmostEqual(line1.angle, 58.28252558853899)
-        self.assertEqual(line1.pen.color().getRgb(), graph.palette[0].getRgb())
+        self.assertEqual(line1.pen.color().hue(), graph.palette[0].hue())
 
         line2 = graph.reg_line_items[2]
         self.assertEqual(line2.pos().x(), 0)
         self.assertEqual(line2.pos().y(), 1)
         self.assertAlmostEqual(line2.angle, np.degrees(np.arctan2(2, 1)))
-        self.assertEqual(line2.pen.color().getRgb(), graph.palette[1].getRgb())
+        self.assertEqual(line2.pen.color().hue(), graph.palette[1].hue())
 
     def test_orthonormal_line(self):
         color = QColor(1, 2, 3)
@@ -1001,11 +1001,11 @@ def test_update_regression_line_calls_add_line(self):
 
         np.testing.assert_equal(args2[0], x[:4])
         np.testing.assert_equal(args2[1], y[:4])
-        self.assertEqual(args2[2], graph.palette[0])
+        self.assertEqual(args2[2].hue(), graph.palette[0].hue())
 
         np.testing.assert_equal(args3[0], x[4:])
         np.testing.assert_equal(args3[1], y[4:])
-        self.assertEqual(args3[2], graph.palette[1])
+        self.assertEqual(args3[2].hue(), graph.palette[1].hue())
         graph._add_line.reset_mock()
 
         # Continuous color - just a single line
@@ -1015,7 +1015,7 @@ def test_update_regression_line_calls_add_line(self):
         args1, _ = graph._add_line.call_args_list[0]
         np.testing.assert_equal(args1[0], x)
         np.testing.assert_equal(args1[1], y)
-        self.assertEqual(args1[2], QColor("#505050"))
+        self.assertEqual(args1[2].hue(), QColor("#505050").hue())
         graph._add_line.reset_mock()
         widget.is_continuous_color = lambda: False
 
@@ -1052,11 +1052,11 @@ def test_update_regression_line_calls_add_line(self):
         (args1, _), (args2, _) = graph._add_line.call_args_list
         np.testing.assert_equal(args1[0], x)
         np.testing.assert_equal(args1[1], y)
-        self.assertEqual(args1[2], QColor("#505050"))
+        self.assertEqual(args1[2].hue(), QColor("#505050").hue())
 
         np.testing.assert_equal(args2[0], x[1:])
         np.testing.assert_equal(args2[1], y[1:])
-        self.assertEqual(args2[2], graph.palette[1])
+        self.assertEqual(args2[2].hue(), graph.palette[1].hue())
 
     def test_update_regression_line_is_called(self):
         widget = self.widget