Skip to content

Commit 9b71ba4

Browse files
committed
OWTranspose: Add a new widget
1 parent 6c51bca commit 9b71ba4

File tree

3 files changed

+425
-0
lines changed

3 files changed

+425
-0
lines changed
Lines changed: 257 additions & 0 deletions
Loading

Orange/widgets/data/owtranspose.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from itertools import chain
2+
3+
from AnyQt.QtCore import Qt
4+
5+
from Orange.data import (Table, ContinuousVariable, DiscreteVariable,
6+
StringVariable, Domain)
7+
from Orange.widgets.settings import (Setting, ContextSetting,
8+
PerfectDomainContextHandler)
9+
from Orange.widgets.utils.itemmodels import DomainModel
10+
from Orange.widgets.widget import OWWidget, Msg
11+
from Orange.widgets import gui
12+
13+
14+
class OWTranspose(OWWidget):
15+
name = "Transpose"
16+
description = "Transpose data table."
17+
icon = "icons/Transpose.svg"
18+
priority = 2000
19+
20+
inputs = [("Data", Table, "set_data")]
21+
outputs = [("Data", Table)]
22+
23+
resizing_enabled = False
24+
want_main_area = False
25+
26+
settingsHandler = PerfectDomainContextHandler(metas_in_res=True)
27+
feature_names_column = ContextSetting("None")
28+
class_variable_index = ContextSetting(0)
29+
auto_apply = Setting(True)
30+
31+
class Error(OWWidget.Error):
32+
value_error = Msg("{}")
33+
34+
def __init__(self):
35+
super().__init__()
36+
self.data = None
37+
38+
# GUI
39+
options = dict(callback=self.apply, orientation=Qt.Horizontal,
40+
labelWidth=100, contentsLength=12)
41+
self.feature_model = DomainModel(
42+
order=DomainModel.METAS, placeholder="None",
43+
valid_types=StringVariable, alphabetical=True)
44+
self.feature_combo = gui.comboBox(
45+
self.controlArea, self, "feature_names_column",
46+
box="Create feature names from", sendSelectedValue=True, **options)
47+
self.feature_combo.setModel(self.feature_model)
48+
49+
self.class_model = DomainModel(
50+
order=DomainModel.ATTRIBUTES, placeholder="None",
51+
valid_types=DomainModel.PRIMITIVE, alphabetical=True)
52+
self.class_combo = gui.comboBox(
53+
self.controlArea, self, "class_variable_index",
54+
box="Class attribute", **options)
55+
self.class_combo.setModel(self.class_model)
56+
57+
self.apply_button = gui.auto_commit(
58+
self.controlArea, self, "auto_apply", "&Apply",
59+
box=False, commit=self.apply)
60+
61+
def set_data(self, data):
62+
self.closeContext()
63+
self.data = data
64+
self.update_controls()
65+
self.openContext(data)
66+
self.class_variable_index = min(self.class_variable_index,
67+
len(self.class_model) - 1)
68+
self.apply()
69+
70+
def update_controls(self):
71+
self.feature_model.set_domain(None)
72+
self.class_model.set_domain(None)
73+
self.feature_names_column = "None"
74+
if self.data:
75+
self.feature_model.set_domain(self.data.domain)
76+
self.feature_names_column = self.data.domain.metas[0].name \
77+
if self.data.domain.metas else "None"
78+
names = chain.from_iterable(
79+
list(a.attributes) for a in self.data.domain.attributes)
80+
variables = chain.from_iterable(
81+
(DiscreteVariable(name), ContinuousVariable(name))
82+
for name in set(names))
83+
self.class_model.set_domain(Domain(list(variables)))
84+
self.class_variable_index = min(1, len(self.class_model) - 1)
85+
86+
def apply(self):
87+
self.clear_messages()
88+
transposed = None
89+
if self.data:
90+
options = dict()
91+
if self.feature_names_column != "None":
92+
options["feature_names_column"] = self.feature_names_column
93+
class_var = self.class_model[self.class_variable_index]
94+
if class_var is not None:
95+
options["class_name"] = class_var.name
96+
options["class_type"] = type(class_var)
97+
98+
try:
99+
transposed = Table.transpose(self.data, **options)
100+
except ValueError as e:
101+
self.Error.value_error(e)
102+
self.send("Data", transposed)
103+
104+
def send_report(self):
105+
class_var = self.class_model[self.class_variable_index] \
106+
if len(self.class_model) else "None"
107+
self.report_items(
108+
"", [("Create feature names from", self.feature_names_column),
109+
("Class variable as", class_var)])
110+
if self.data:
111+
self.report_data("Data", self.data)
112+
113+
114+
if __name__ == "__main__":
115+
from AnyQt.QtWidgets import QApplication
116+
117+
app = QApplication([])
118+
ow = OWTranspose()
119+
d = Table("zoo")
120+
d.domain.attributes[0].attributes = {"key": "value"}
121+
ow.set_data(d)
122+
ow.show()
123+
app.exec_()
124+
ow.saveSettings()

0 commit comments

Comments
 (0)