Repository: biolab/orange3

Issue:
Weird behavior when changinf number of PCs
- [x] **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 (```). -->
There might be a bug in the way the `PCA` widget is outputing the PCs. I recorded the a screencast that I uploaded [here](https://drive.google.com/file/d/1dtR_cw0HaMlq3qo3R_3SL0bpiY9V1sn2/view?usp=sharing). 

- [x] **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...) -->
Consider this workflow:
![image](https://user-images.githubusercontent.com/6304794/97450469-11f18700-1933-11eb-980f-3142ca3b00fa.png)
 Only the `PCA (1)` branch is relevant.

`Datasets` provides the _Liver Spectroscopy_ dataset. I remove all features in `Select Columns` and change the PCs from _Meta Attribute_ to _Feature_. Then, I change the number of calculated PCs in the `PCA` widget. If I increase the number of PCs the new PC is added as a meta column, which is logical. If I decrease the number of PCs though, everything is added as a meta column, except PC1. This doesn't seem to make sense.

If I connect the "Transformed Data" output of `PCA` to `Select Columns` I can produce some other crazy behavior, where it seems that the PCs are switched between _Features_ and _Meta Attributes_ randomly.

Also, `Select Columns` often (not always) updates only when I click its window.

- [x] **Which version of Orange are you using? How did you install Orange?**
Orange: 3.28.0.dev0+1d29cf9

- [x] **What is your operating system?**
OS X 10.15.7








Discussion:
What happens if you reset saved widget settings prior to doing this?

This seems to be more of a problem of Select Columns (if it really is a problem, perhaps it is a feature - contexts) than of the PCA widget. Is this correct or did you also get strange outputs from the PCA widget?
I get very similar behavior after resetting the widget settings.
You might be right about this being a problem with Select Columns though. 

Sometimes Select Columns updates without clicking it, sometimes not.

When I decreased the number of PCs from 5 to 4 I got this. Now it removed PC3...
![image](https://user-images.githubusercontent.com/6304794/97456614-52ec9a00-1939-11eb-947e-0048ee6dbca2.png)


Resolving patch:
diff --git a/Orange/widgets/data/owselectcolumns.py b/Orange/widgets/data/owselectcolumns.py
--- a/Orange/widgets/data/owselectcolumns.py
+++ b/Orange/widgets/data/owselectcolumns.py
@@ -116,6 +116,9 @@ def decode_setting(self, setting, value, domain=None, *_args):
         return decoded
 
     def match(self, context, domain, attrs, metas):
+        if context.attributes == attrs and context.metas == metas:
+            return self.PERFECT_MATCH
+
         if not "domain_role_hints" in context.values:
             return self.NO_MATCH
 
diff --git a/Orange/widgets/settings.py b/Orange/widgets/settings.py
--- a/Orange/widgets/settings.py
+++ b/Orange/widgets/settings.py
@@ -203,6 +203,9 @@ def _var_exists(cls, setting, value, attributes, metas):
                 metas.get(attr_name, -1) == attr_type)
 
     def match(self, context, domain, attrs, metas):
+        if context.attributes == attrs and context.metas == metas:
+            return self.PERFECT_MATCH
+
         matches = []
         try:
             for setting, data, _ in \


Test patch:
diff --git a/Orange/widgets/visualize/tests/test_owlinearprojection.py b/Orange/widgets/visualize/tests/test_owlinearprojection.py
--- a/Orange/widgets/visualize/tests/test_owlinearprojection.py
+++ b/Orange/widgets/visualize/tests/test_owlinearprojection.py
@@ -178,7 +178,7 @@ def test_invalidated_model_selected(self):
 
         self.widget.setup_plot.reset_mock()
         self.send_signal(self.widget.Inputs.data, self.data)
-        self.widget.setup_plot.assert_not_called()
+        self.widget.setup_plot.assert_called_once()
 
     def test_two_classes_dataset(self):
         self.widget.radio_placement.buttons[1].click()
diff --git a/Orange/widgets/visualize/tests/test_owradviz.py b/Orange/widgets/visualize/tests/test_owradviz.py
--- a/Orange/widgets/visualize/tests/test_owradviz.py
+++ b/Orange/widgets/visualize/tests/test_owradviz.py
@@ -128,4 +128,4 @@ def test_invalidated_model_selected(self):
 
         self.widget.setup_plot.reset_mock()
         self.send_signal(self.widget.Inputs.data, self.data)
-        self.widget.setup_plot.assert_not_called()
+        self.widget.setup_plot.assert_called_once()