Skip to content

Commit a89c640

Browse files
committed
PCA: Add a signal with original data + pca
1 parent 04b7c72 commit a89c640

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

Orange/widgets/unsupervised/owpca.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Inputs:
3131

3232
class Outputs:
3333
transformed_data = Output("Transformed Data", Table, replaces=["Transformed data"])
34+
data = Output("Data", Table, default=True)
3435
components = Output("Components", Table)
3536
pca = Output("PCA", PCA, dynamic=False)
3637

@@ -180,6 +181,7 @@ def clear(self):
180181

181182
def clear_outputs(self):
182183
self.Outputs.transformed_data.send(None)
184+
self.Outputs.data.send(None)
183185
self.Outputs.components.send(None)
184186
self.Outputs.pca.send(self._pca_projector)
185187

@@ -286,7 +288,7 @@ def _update_axis(self):
286288
axis.setTicks([[(i, str(i)) for i in range(1, p + 1, d)]])
287289

288290
def commit(self):
289-
transformed = components = None
291+
transformed = data = components = None
290292
if self._pca is not None:
291293
if self._transformed is None:
292294
# Compute the full transform (MAX_COMPONENTS components) once.
@@ -311,9 +313,18 @@ def commit(self):
311313
metas=metas)
312314
components.name = 'components'
313315

316+
data_dom = Domain(
317+
self.data.domain.attributes,
318+
self.data.domain.class_vars,
319+
self.data.domain.metas + domain.attributes)
320+
data = Table.from_numpy(
321+
data_dom, self.data.X, self.data.Y,
322+
numpy.hstack((self.data.metas, transformed.X)))
323+
314324
self._pca_projector.component = self.ncomponents
315325
self.Outputs.transformed_data.send(transformed)
316326
self.Outputs.components.send(components)
327+
self.Outputs.data.send(data)
317328
self.Outputs.pca.send(self._pca_projector)
318329

319330
def send_report(self):

Orange/widgets/unsupervised/tests/test_owpca.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,28 @@ def test_on_cut_changed(self):
220220
invalidate.assert_not_called()
221221
self.assertEqual(widget.ncomponents, 0)
222222

223+
def test_output_data(self):
224+
widget = self.widget
225+
widget.ncomponents = 2
226+
domain = Domain(self.iris.domain.attributes[:3],
227+
self.iris.domain.class_var,
228+
self.iris.domain.attributes[3:])
229+
iris = self.iris.transform(domain)
230+
self.send_signal(widget.Inputs.data, iris)
231+
output = self.get_output(widget.Outputs.data)
232+
outdom = output.domain
233+
self.assertEqual(domain.attributes, outdom.attributes)
234+
self.assertEqual(domain.class_var, outdom.class_var)
235+
self.assertEqual(domain.metas, outdom.metas[:1])
236+
self.assertEqual(len(outdom.metas), 3)
237+
np.testing.assert_equal(iris.X, output.X)
238+
np.testing.assert_equal(iris.Y, output.Y)
239+
np.testing.assert_equal(iris.metas[:, 0], output.metas[:, 0])
240+
241+
trans = self.get_output(widget.Outputs.transformed_data)
242+
self.assertEqual(trans.domain.attributes, outdom.metas[1:])
243+
np.testing.assert_equal(trans.X, output.metas[:, 1:])
244+
223245

224246
if __name__ == "__main__":
225247
unittest.main()

0 commit comments

Comments
 (0)