source: orange/orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 9626:be4431a54561

Revision 9626:be4431a54561, 72.8 KB checked in by Miha Stajdohar <miha.stajdohar@…>, 2 years ago (diff)

Who misspelled priority in the widget header!?

Line 
1"""
2<name>Net Explorer</name>
3<description>Orange widget for network exploration.</description>
4<icon>icons/Network.png</icon>
5<contact>Miha Stajdohar (miha.stajdohar(@at@)gmail.com)</contact> 
6<priority>6420</priority>
7"""
8import math
9import operator
10import statc
11import time
12
13import Orange
14import OWGUI
15import OWColorPalette
16import orngMDS
17
18from OWWidget import *
19from operator import itemgetter
20
21try:
22    from OWNxCanvasQt import *
23
24    class OWNxExplorer(OWWidget):
25
26        settingsList = ["autoSendSelection", "spinExplicit", "spinPercentage",
27        "maxLinkSize", "minVertexSize", "maxVertexSize", "networkCanvas.animate_plot",
28        "networkCanvas.animate_points", "networkCanvas.antialias_plot",
29        "networkCanvas.antialias_points", "networkCanvas.antialias_lines",
30        "networkCanvas.auto_adjust_performance", "invertSize", "optMethod",
31        "lastVertexSizeColumn", "lastColorColumn", "networkCanvas.show_indices", "networkCanvas.show_weights",
32        "lastNameComponentAttribute", "lastLabelColumns", "lastTooltipColumns",
33        "showWeights", "showEdgeLabels", "colorSettings",
34        "selectedSchemaIndex", "edgeColorSettings", "selectedEdgeSchemaIndex",
35        "showMissingValues", "fontSize", "mdsTorgerson", "mdsAvgLinkage",
36        "mdsSteps", "mdsRefresh", "mdsStressDelta", "organism", "showTextMiningInfo",
37        "toolbarSelection", "minComponentEdgeWidth", "maxComponentEdgeWidth",
38        "mdsFromCurrentPos", "labelsOnMarkedOnly", "tabIndex",
39        "networkCanvas.trim_label_words", "opt_from_curr", "networkCanvas.explore_distances",
40        "networkCanvas.show_component_distances", "fontWeight", "networkCanvas.state",
41        "networkCanvas.selection_behavior"]
42
43        def __init__(self, parent=None, signalManager=None, name='Net Explorer',
44                     NetworkCanvas=OWNxCanvas):
45            OWWidget.__init__(self, parent, signalManager, name, noReport=True)
46            #self.contextHandlers = {"": DomainContextHandler("", [ContextField("attributes", selected="markerAttributes"), ContextField("attributes", selected="tooltipAttributes"), "color"])}
47            self.inputs = [("Network", Orange.network.Graph, self.set_graph, Default),
48                           ("Items", Orange.data.Table, self.set_items),
49                           ("Item Subset", Orange.data.Table, self.mark_items),
50                           ("Distances", Orange.core.SymMatrix, self.set_items_distance_matrix),
51                           ("Net View", Orange.network.NxView, self.set_network_view)]
52
53            self.outputs = [("Selected Network", Orange.network.Graph),
54                            ("Distance Matrix", Orange.core.SymMatrix),
55                            ("Marked Items", Orange.data.Table),
56                            ("Selected Items", Orange.data.Table),
57                            ("Other Items", Orange.data.Table)]
58                            #("Attribute Selection List", AttributeList)]
59
60            self.networkCanvas = NetworkCanvas(self, self.mainArea, "Net Explorer")
61
62            self.markerAttributes = []
63            self.tooltipAttributes = []
64            self.edgeLabelAttributes = []
65            self.attributes = []
66            self.edgeAttributes = []
67            self.autoSendSelection = False
68            self.graphShowGrid = 1  # show gridlines in the graph
69            self.markNConnections = 2
70            self.markNumber = 0
71            self.markProportion = 0
72            self.markSearchString = ""
73            self.markDistance = 2
74            self.frSteps = 1
75            self.hubs = 0
76            self.color = 0
77            self.edgeColor = 0
78            self.vertexSize = 0
79            self.nShown = self.nHidden = self.nMarked = self.nSelected = self.verticesPerEdge = self.edgesPerVertex = 0
80            self.optimizeWhat = 1
81            self.maxLinkSize = 3
82            self.maxVertexSize = 7
83            self.minVertexSize = 12
84            self.labelsOnMarkedOnly = 0
85            self.invertSize = 0
86            self.optMethod = 0
87            self.lastVertexSizeColumn = ''
88            self.lastColorColumn = ''
89            self.lastNameComponentAttribute = ''
90            self.lastLabelColumns = set()
91            self.lastTooltipColumns = set()
92            self.showWeights = 0
93            self.showEdgeLabels = 0
94            self.colorSettings = None
95            self.selectedSchemaIndex = 0
96            self.edgeColorSettings = [('net_edges', [[], [('contPalette', (4294967295L, 4278190080L, 0))], [('discPalette', [(204, 204, 204), (179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201), (255, 242, 174), (241, 226, 204)])]]), ('Default', [[], [('contPalette', (4294967295L, 4278190080L, 0))], [('discPalette', [(0, 0, 255), (255, 0, 0), (0, 255, 0), (255, 128, 0), (255, 255, 0), (255, 0, 255), (0, 255, 255), (128, 0, 255), (0, 128, 255), (255, 223, 128), (127, 111, 64), (92, 46, 0), (0, 84, 0), (192, 192, 0), (0, 127, 127), (128, 0, 0), (127, 0, 127)])]])]
97            self.selectedEdgeSchemaIndex = 0
98            self.items_matrix = None
99            self.showDistances = 0
100            self.showMissingValues = 0
101            self.fontSize = 12
102            self.fontWeight = 1
103            self.mdsTorgerson = 0
104            self.mdsAvgLinkage = 1
105            self.mdsSteps = 10000
106            self.mdsRefresh = 50
107            self.mdsStressDelta = 0.0000001
108            self.organism = 'goa_human'
109            self.showTextMiningInfo = 0
110            self.toolbarSelection = 0
111            self.minComponentEdgeWidth = 10
112            self.maxComponentEdgeWidth = 70
113            self.mdsFromCurrentPos = 0
114            self.tabIndex = 0
115            self.number_of_nodes_label = -1
116            self.number_of_edges_label = -1
117            self.opt_from_curr = False
118
119            self.checkSendMarkedNodes = True
120            self.checkSendSelectedNodes = True
121            self.explore_distances = False
122
123            self.loadSettings()
124
125            self._network_view = None
126            self.graph = None
127            self.graph_base = None
128            self.markInputItems = None
129
130            # if optimization method is set to FragViz, set it to FR
131            if self.optMethod == 9:
132                self.optMethod = 3
133
134            self.networkCanvas.showMissingValues = self.showMissingValues
135            self.mainArea.layout().addWidget(self.networkCanvas)
136
137            self.networkCanvas.maxLinkSize = self.maxLinkSize
138
139            self.tabs = OWGUI.tabWidget(self.controlArea)
140
141            self.verticesTab = OWGUI.createTabPage(self.tabs, "Nodes")
142            self.edgesTab = OWGUI.createTabPage(self.tabs, "Edges")
143            self.markTab = OWGUI.createTabPage(self.tabs, "Mark")
144            self.infoTab = OWGUI.createTabPage(self.tabs, "Info")
145            self.performanceTab = OWGUI.createTabPage(self.tabs, "Performance")
146
147            self.tabs.setCurrentIndex(self.tabIndex)
148            self.connect(self.tabs, SIGNAL("currentChanged(int)"), lambda index: setattr(self, 'tabIndex', index))
149
150            self.optimizeBox = OWGUI.radioButtonsInBox(self.verticesTab, self, "optimizeWhat", [], "Optimize", addSpace=False)
151
152            self.optCombo = OWGUI.comboBox(self.optimizeBox, self, "optMethod", label='Method:     ', orientation='horizontal', callback=self.graph_layout_method)
153            self.optCombo.addItem("No optimization")
154            self.optCombo.addItem("Random")
155            self.optCombo.addItem("Fruchterman Reingold")
156            self.optCombo.addItem("Fruchterman Reingold Weighted")
157            self.optCombo.addItem("Fruchterman Reingold Radial")
158            self.optCombo.addItem("Circular Crossing Reduction")
159            self.optCombo.addItem("Circular Original")
160            self.optCombo.addItem("Circular Random")
161            self.optCombo.addItem("FragViz")
162            self.optCombo.addItem("MDS")
163            self.optCombo.addItem("Pivot MDS")
164            self.optCombo.setCurrentIndex(self.optMethod)
165            self.stepsSpin = OWGUI.spin(self.optimizeBox, self, "frSteps", 1, 100000, 1, label="Iterations: ")
166            self.cb_opt_from_curr = OWGUI.checkBox(self.optimizeBox, self, "opt_from_curr", label="Optimize from current positions")
167            self.cb_opt_from_curr.setEnabled(False)
168            self.stepsSpin.setEnabled(False)
169
170            self.optButton = OWGUI.button(self.optimizeBox, self, "Optimize layout", callback=self.graph_layout, toggleButton=1)
171
172            colorBox = OWGUI.widgetBox(self.verticesTab, "Node color attribute", orientation="horizontal", addSpace=False)
173            self.colorCombo = OWGUI.comboBox(colorBox, self, "color", callback=self.set_node_colors)
174            self.colorCombo.addItem("(same color)")
175            OWGUI.button(colorBox, self, "palette", self._set_colors, tooltip="Set node color palette", width=60, debuggingEnabled=0)
176
177            ib = OWGUI.widgetBox(self.verticesTab, "Node size attribute", orientation="vertical", addSpace=False)
178            hb = OWGUI.widgetBox(ib, orientation="horizontal", addSpace=False)
179            OWGUI.checkBox(hb, self, "invertSize", "Invert size", callback=self.set_node_sizes)
180            OWGUI.spin(hb, self, "minVertexSize", 5, 200, 1, label="Min:", callback=self.set_node_sizes)
181            OWGUI.spin(hb, self, "maxVertexSize", 5, 200, 1, label="Max:", callback=self.set_node_sizes)
182            self.vertexSizeCombo = OWGUI.comboBox(ib, self, "vertexSize", callback=self.set_node_sizes)
183            self.vertexSizeCombo.addItem("(none)")
184
185            self.attBox = OWGUI.widgetBox(self.verticesTab, "Node labels | tooltips", orientation="vertical", addSpace=False)
186            hb = OWGUI.widgetBox(self.attBox, orientation="horizontal", addSpace=False)
187            self.attListBox = OWGUI.listBox(hb, self, "markerAttributes", "attributes", selectionMode=QListWidget.MultiSelection, callback=self._clicked_att_lstbox)
188            self.tooltipListBox = OWGUI.listBox(hb, self, "tooltipAttributes", "attributes", selectionMode=QListWidget.MultiSelection, callback=self._clicked_tooltip_lstbox)
189            OWGUI.spin(self.attBox, self, "networkCanvas.trim_label_words", 0, 5, 1, label='Trim label words to', callback=self._clicked_att_lstbox)
190
191            ib = OWGUI.widgetBox(self.edgesTab, "General", orientation="vertical")
192            OWGUI.checkBox(ib, self, 'networkCanvas.show_weights', 'Show weights', callback=self.networkCanvas.set_edge_labels)
193            #OWGUI.checkBox(ib, self, 'showEdgeLabels', 'Show labels on edges', callback=(lambda: self._set_canvas_attr('showEdgeLabels', self.showEdgeLabels)))
194            OWGUI.spin(ib, self, "maxLinkSize", 1, 50, 1, label="Max edge width:", callback=self.set_edge_sizes)
195            self.cb_show_distances = OWGUI.checkBox(ib, self, 'explore_distances', 'Explore node distances', callback=self.set_explore_distances, disabled=1)
196            self.cb_show_component_distances = OWGUI.checkBox(ib, self, 'networkCanvas.show_component_distances', 'Show component distances', callback=self.networkCanvas.set_show_component_distances, disabled=1)
197
198            colorBox = OWGUI.widgetBox(self.edgesTab, "Edge color attribute", orientation="horizontal", addSpace=False)
199            self.edgeColorCombo = OWGUI.comboBox(colorBox, self, "edgeColor", callback=self.set_edge_colors)
200            self.edgeColorCombo.addItem("(same color)")
201            OWGUI.button(colorBox, self, "palette", self._set_edge_color_palette, tooltip="Set edge color palette", width=60, debuggingEnabled=0)
202
203            self.edgeLabelBox = OWGUI.widgetBox(self.edgesTab, "Edge labels", addSpace=False)
204            self.edgeLabelListBox = OWGUI.listBox(self.edgeLabelBox, self, "edgeLabelAttributes", "edgeAttributes", selectionMode=QListWidget.MultiSelection, callback=self._clicked_edge_label_listbox)
205            #self.edgeLabelBox.setEnabled(False)
206
207            ib = OWGUI.widgetBox(self.verticesTab, "General", orientation="vertical")
208            OWGUI.checkBox(ib, self, 'networkCanvas.show_indices', 'Show indices', callback=self.networkCanvas.set_node_labels)
209            OWGUI.checkBox(ib, self, 'labelsOnMarkedOnly', 'Show labels on marked nodes only', callback=(lambda: self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)))
210            OWGUI.spin(ib, self, "fontSize", 4, 30, 1, label="Font size:", callback=self.set_font)
211            self.comboFontWeight = OWGUI.comboBox(ib, self, "fontWeight", label='Font weight:', orientation='horizontal', callback=self.set_font)
212            self.comboFontWeight.addItem("Normal")
213            self.comboFontWeight.addItem("Bold")
214            self.comboFontWeight.setCurrentIndex(self.fontWeight)
215
216            ib = OWGUI.widgetBox(self.markTab, "Info", orientation="vertical")
217            OWGUI.label(ib, self, "Nodes (shown/hidden): %(number_of_nodes_label)i (%(nShown)i/%(nHidden)i)")
218            OWGUI.label(ib, self, "Selected: %(nSelected)i, marked: %(nMarked)i")
219
220            ribg = OWGUI.radioButtonsInBox(self.markTab, self, "hubs", [], "Mark", callback=self.set_mark_mode)
221            OWGUI.appendRadioButton(ribg, self, "hubs", "None", callback=self.set_mark_mode)
222            OWGUI.appendRadioButton(ribg, self, "hubs", "Search", callback=self.set_mark_mode)
223            self.ctrlMarkSearchString = OWGUI.lineEdit(OWGUI.indentedBox(ribg), self, "markSearchString", callback=self._set_search_string_timer, callbackOnType=True)
224            self.searchStringTimer = QTimer(self)
225            self.connect(self.searchStringTimer, SIGNAL("timeout()"), self.set_mark_mode)
226
227            OWGUI.appendRadioButton(ribg, self, "hubs", "Neighbors of focused", callback=self.set_mark_mode)
228            OWGUI.appendRadioButton(ribg, self, "hubs", "Neighbours of selected", callback=self.set_mark_mode)
229            ib = OWGUI.indentedBox(ribg, orientation=0)
230            self.ctrlMarkDistance = OWGUI.spin(ib, self, "markDistance", 0, 100, 1, label="Distance ", callback=(lambda h=2: self.set_mark_mode(h)))
231            #self.ctrlMarkFreeze = OWGUI.button(ib, self, "&Freeze", value="graph.freezeNeighbours", toggleButton = True)
232            OWGUI.widgetLabel(ribg, "Mark nodes with ...")
233            OWGUI.appendRadioButton(ribg, self, "hubs", "at least N connections", callback=self.set_mark_mode)
234            OWGUI.appendRadioButton(ribg, self, "hubs", "at most N connections", callback=self.set_mark_mode)
235            self.ctrlMarkNConnections = OWGUI.spin(OWGUI.indentedBox(ribg), self, "markNConnections", 0, 1000000, 1, label="N ", callback=(lambda h=4: self.set_mark_mode(h)))
236            OWGUI.appendRadioButton(ribg, self, "hubs", "more connections than any neighbour", callback=self.set_mark_mode)
237            OWGUI.appendRadioButton(ribg, self, "hubs", "more connections than avg neighbour", callback=self.set_mark_mode)
238            OWGUI.appendRadioButton(ribg, self, "hubs", "most connections", callback=self.set_mark_mode)
239            ib = OWGUI.indentedBox(ribg)
240            self.ctrlMarkNumber = OWGUI.spin(ib, self, "markNumber", 0, 1000000, 1, label="Number of nodes:", callback=(lambda h=8: self.set_mark_mode(h)))
241            OWGUI.widgetLabel(ib, "(More nodes are marked in case of ties)")
242            self.markInputRadioButton = OWGUI.appendRadioButton(ribg, self, "hubs", "Mark nodes given in the input signal", callback=self.set_mark_mode)
243            ib = OWGUI.indentedBox(ribg)
244            self.markInput = 0
245            self.markInputCombo = OWGUI.comboBox(ib, self, "markInput", callback=(lambda h=9: self.set_mark_mode(h)))
246            self.markInputRadioButton.setEnabled(False)
247
248            #ib = OWGUI.widgetBox(self.markTab, "General", orientation="vertical")
249            #self.checkSendMarkedNodes = True
250            #OWGUI.checkBox(ib, self, 'checkSendMarkedNodes', 'Send marked nodes', callback = self.send_marked_nodes, disabled=0)
251
252            self.toolbar = OWGUI.widgetBox(self.controlArea, orientation='horizontal')
253            prevstate = self.networkCanvas.state
254            prevselbeh = self.networkCanvas.selection_behavior
255            G = self.networkCanvas.gui
256            self.zoomSelectToolbar = G.zoom_select_toolbar(self.toolbar, nomargin=True, buttons=
257                G.default_zoom_select_buttons +
258                [
259                    G.Spacing,
260                    ("buttonM2S", "Marked to selection", None, None, "marked_to_selected", 'Dlg_Mark2Sel'),
261                    ("buttonS2M", "Selection to marked", None, None, "selected_to_marked", 'Dlg_Sel2Mark'),
262                    ("buttonHSEL", "Hide selection", None, None, "hide_selection", 'Dlg_HideSelection'),
263                    ("buttonSSEL", "Show all nodes", None, None, "show_selection", 'Dlg_ShowSelection'),
264                    #("buttonUN", "Hide unselected", None, None, "hideUnSelectedVertices", 'Dlg_SelectedNodes'),
265                    #("buttonSW", "Show all nodes", None, None, "showAllVertices", 'Dlg_clear'),
266                ])
267            self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_data)
268            self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_marked_nodes)
269            self.zoomSelectToolbar.buttons[("buttonHSEL", "Hide selection", None, None, "hide_selection", 'Dlg_HideSelection')].clicked.connect(self.hide_selection)
270            self.zoomSelectToolbar.buttons[("buttonSSEL", "Show all nodes", None, None, "show_selection", 'Dlg_ShowSelection')].clicked.connect(self.show_selection)
271            #self.zoomSelectToolbar.buttons[G.SendSelection].hide()
272            self.zoomSelectToolbar.select_selection_behaviour(prevselbeh)
273            self.zoomSelectToolbar.select_state(prevstate)
274
275            ib = OWGUI.widgetBox(self.infoTab, "General")
276            OWGUI.label(ib, self, "Number of nodes: %(number_of_nodes_label)i")
277            OWGUI.label(ib, self, "Number of edges: %(number_of_edges_label)i")
278            OWGUI.label(ib, self, "Nodes per edge: %(verticesPerEdge).2f")
279            OWGUI.label(ib, self, "Edges per node: %(edgesPerVertex).2f")
280
281            ib = OWGUI.widgetBox(self.infoTab, orientation="horizontal")
282
283            OWGUI.button(ib, self, "Save net", callback=self.save_network, debuggingEnabled=False)
284            OWGUI.button(ib, self, "Save img", callback=self.networkCanvas.saveToFile, debuggingEnabled=False)
285            self.reportButton = OWGUI.button(ib, self, "&Report", self.reportAndFinish, debuggingEnabled=0)
286            self.reportButton.setAutoDefault(0)
287
288            #OWGUI.button(self.edgesTab, self, "Clustering", callback=self.clustering)
289            ib = OWGUI.widgetBox(self.infoTab, "Edit")
290            self.editAttribute = 0
291            self.editCombo = OWGUI.comboBox(ib, self, "editAttribute", label="Edit attribute:", orientation="horizontal")
292            self.editCombo.addItem("Select attribute")
293            self.editValue = ''
294            hb = OWGUI.widgetBox(ib, orientation="horizontal")
295            OWGUI.lineEdit(hb, self, "editValue", "Value:", orientation='horizontal')
296            OWGUI.button(hb, self, "Set", callback=self.edit)
297
298            ib = OWGUI.widgetBox(self.infoTab, "Prototype")
299            ib.setVisible(True)
300
301            OWGUI.lineEdit(ib, self, "organism", "Organism:", orientation='horizontal')
302
303            self.nameComponentAttribute = 0
304            self.nameComponentCombo = OWGUI.comboBox(ib, self, "nameComponentAttribute", callback=self.nameComponents, label="Name components:", orientation="horizontal")
305            self.nameComponentCombo.addItem("Select attribute")
306
307            self.showComponentAttribute = 0
308            self.showComponentCombo = OWGUI.comboBox(ib, self, "showComponentAttribute", callback=self.showComponents, label="Labels on components:", orientation="horizontal")
309            self.showComponentCombo.addItem("Select attribute")
310            OWGUI.checkBox(ib, self, 'showTextMiningInfo', "Show text mining info")
311
312            #OWGUI.spin(ib, self, "rotateSteps", 1, 10000, 1, label="Rotate max steps: ")
313            OWGUI.spin(ib, self, "minComponentEdgeWidth", 0, 100, 1, label="Min component edge width: ", callback=(lambda changedMin=1: self.set_component_edge_width(changedMin)))
314            OWGUI.spin(ib, self, "maxComponentEdgeWidth", 0, 200, 1, label="Max component edge width: ", callback=(lambda changedMin=0: self.set_component_edge_width(changedMin)))
315
316            self.attSelectionAttribute = 0
317            self.comboAttSelection = OWGUI.comboBox(ib, self, "attSelectionAttribute", label='Send attribute selection list:', orientation='horizontal', callback=self.sendAttSelectionList)
318            self.comboAttSelection.addItem("Select attribute")
319            self.autoSendAttributes = 0
320            OWGUI.checkBox(ib, self, 'autoSendAttributes', "auto send attributes", callback=self.setAutoSendAttributes)
321
322            self.icons = self.createAttributeIconDict()
323            self.set_mark_mode()
324
325            self.networkCanvas.gui.effects_box(self.performanceTab)
326
327            self.verticesTab.layout().addStretch(1)
328            self.edgesTab.layout().addStretch(1)
329            self.markTab.layout().addStretch(1)
330            self.infoTab.layout().addStretch(1)
331            self.performanceTab.layout().addStretch(1)
332
333            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
334            self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
335            self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
336
337            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
338            self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
339            self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
340
341            self.graph_layout_method()
342            self.set_font()
343            self.set_graph(None)
344
345            self.setMinimumWidth(900)
346
347            self.connect(self.networkCanvas, SIGNAL("marked_points_changed()"), self.send_marked_nodes)
348            self.connect(self.networkCanvas, SIGNAL("selection_changed()"), self.send_data)
349
350        def hide_selection(self):
351            nodes = set(self.graph.nodes()).difference(self.networkCanvas.selected_nodes())
352            self.change_graph(Orange.network.nx.Graph.subgraph(self.graph, nodes))
353
354        def show_selection(self):
355            self.change_graph(self.graph_base)
356
357        def edit(self):
358            if self.graph is None:
359                return
360
361            vars = [x.name for x in self.graph_base.items_vars()]
362            if not self.editCombo.currentText() in vars:
363                return
364            att = str(self.editCombo.currentText())
365            vertices = self.networkCanvas.selected_nodes()
366
367            if len(vertices) == 0:
368                return
369
370            items = self.graph_base.items()
371            if items.domain[att].var_type == Orange.data.Type.Continuous:
372                for v in vertices:
373                    items[v][att] = float(self.editValue)
374            else:
375                for v in vertices:
376                    items[v][att] = str(self.editValue)
377
378        def set_items_distance_matrix(self, matrix):
379            self.error()
380            self.warning()
381            self.information()
382
383            self.cb_show_distances.setEnabled(0)
384            self.cb_show_component_distances.setEnabled(0)
385
386            if matrix is None or self.graph_base is None:
387                self.items_matrix = None
388                self.networkCanvas.items_matrix = None
389                self.information('No graph found!')
390                return
391
392            if matrix.dim != self.graph_base.number_of_nodes():
393                self.error('The number of vertices does not match matrix size.')
394                self.items_matrix = None
395                self.networkCanvas.items_matrix = None
396                return
397
398            self.items_matrix = matrix
399            self.networkCanvas.items_matrix = matrix
400            self.cb_show_distances.setEnabled(1)
401            self.cb_show_component_distances.setEnabled(1)
402
403            if str(self.optMethod) in ['8', '9', '10']:
404                if self.items_matrix is not None and self.graph is not None and \
405                self.items_matrix.dim == self.graph.number_of_nodes():
406                    self.optButton.setEnabled(True)
407                    self.optButton.setChecked(True)
408                    self.graph_layout()
409
410        def _set_canvas_attr(self, attr, value):
411            setattr(self.networkCanvas, attr, value)
412            self.networkCanvas.updateCanvas()
413
414        def _set_curve_attr(self, attr, value):
415            setattr(self.networkCanvas.networkCurve, attr, value)
416            self.networkCanvas.updateCanvas()
417
418        def _set_search_string_timer(self):
419            self.hubs = 1
420            self.searchStringTimer.stop()
421            self.searchStringTimer.start(1000)
422
423        def set_mark_mode(self, i=None):
424            self.searchStringTimer.stop()
425            if not i is None:
426                self.hubs = i
427
428            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.networkCanvas.mark_on_selection_changed)
429            QObject.disconnect(self.networkCanvas, SIGNAL('point_hovered(Point*)'), self.networkCanvas.mark_on_focus_changed)
430
431            if self.graph is None:
432                return
433
434            hubs = self.hubs
435
436            if hubs in [0, 1, 2, 3]:
437                if hubs == 0:
438                    self.networkCanvas.networkCurve.clear_node_marks()
439                elif hubs == 1:
440                    #print "mark on given label"
441                    txt = self.markSearchString
442
443                    toMark = set(i for i, values in enumerate(self.graph_base.items()) if txt.lower() in " ".join([str(values[ndx]).decode("ascii", "ignore").lower() for ndx in range(len(self.graph_base.items().domain)) + self.graph_base.items().domain.getmetas().keys()]))
444                    toMark = toMark.intersection(self.graph.nodes())
445                    self.networkCanvas.networkCurve.clear_node_marks()
446                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) for i in toMark))
447                elif hubs == 2:
448                    #print "mark on focus"
449                    self.networkCanvas.mark_neighbors = self.markDistance
450                    QObject.connect(self.networkCanvas, SIGNAL('point_hovered(Point*)'), self.networkCanvas.mark_on_focus_changed)
451                elif hubs == 3:
452                    #print "mark selected"
453                    self.networkCanvas.mark_neighbors = self.markDistance
454                    QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.networkCanvas.mark_on_selection_changed)
455                    self.networkCanvas.mark_on_selection_changed()
456
457            elif hubs in [4, 5, 6, 7, 8, 9]:
458
459                powers = sorted(self.graph.degree_iter(), key=itemgetter(1), reverse=True)
460
461                if hubs == 4:
462                    #print "mark at least N connections"
463                    N = self.markNConnections
464                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
465                        d >= N else (i, False) for i, d in powers))
466                elif hubs == 5:
467                    #print "mark at most N connections"
468                    N = self.markNConnections
469                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
470                        d <= N else (i, False) for i, d in powers))
471                elif hubs == 6:
472                    #print "mark more than any"
473                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
474                        d > max([0] + self.graph.degree(self.graph.neighbors(i)).values()) \
475                        else (i, False) for i, d in powers))
476                elif hubs == 7:
477                    #print "mark more than avg"
478                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
479                        d > statc.mean([0] + self.graph.degree(self.graph.neighbors(i)).values()) \
480                        else (i, False) for i, d in powers))
481                    self.networkCanvas.replot()
482                elif hubs == 8:
483                    #print "mark most"
484                    self.networkCanvas.networkCurve.clear_node_marks()
485
486                    if self.markNumber < 1:
487                        return
488
489                    cut = self.markNumber
490                    cutPower = powers[cut - 1][1]
491                    while cut < len(powers) and powers[cut][1] == cutPower:
492                        cut += 1
493
494                    self.networkCanvas.networkCurve.clear_node_marks()
495                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) for \
496                        i, d in powers[:cut]))
497
498                elif hubs == 9:
499                    var = str(self.markInputCombo.currentText())
500                    if self.markInputItems is not None and len(self.markInputItems) > 0:
501                        if var == 'ID':
502                            values = [x.id for x in self.markInputItems]
503                            tomark = dict((x, True) for x in self.graph.nodes() if self.graph_base.items()[x].id in values)
504                        else:
505                            values = [str(x[var]).strip().upper() for x in self.markInputItems]
506                            tomark = dict((x, True) for x in self.graph.nodes() if str(self.graph_base.items()[x][var]).strip().upper() in values)
507                        self.networkCanvas.networkCurve.clear_node_marks()
508                        self.networkCanvas.networkCurve.set_node_marks(tomark)
509
510                    else:
511                        self.networkCanvas.networkCurve.clear_node_marks()
512
513            self.nMarked = len(self.networkCanvas.marked_nodes())
514
515        def save_network(self):
516    #        if self.networkCanvas is None or self.graph is None:
517    #            return
518    #       
519    #        filename = QFileDialog.getSaveFileName(self, 'Save Network File', '', 'NetworkX graph as Python pickle (*.gpickle)\nPajek network (*.net)\nGML network (*.gml)')
520    #        if filename:
521    #            fn = ""
522    #            head, tail = os.path.splitext(str(filename))
523    #            if not tail:
524    #                fn = head + ".net"
525    #            else:
526    #                fn = str(filename)
527    #           
528    #            for i in range(self.graph.number_of_nodes()):
529    #                node = self.graph.node[i]
530    #                node['x'] = self.layout.coors[0][i]
531    #                node['y'] = self.layout.coors[1][i]
532    #
533    #            Orange.network.readwrite.write(self.graph, fn)
534            pass
535
536        def send_data(self):
537            if len(self.signalManager.getLinks(self, None, \
538                "Selected Items", None)) > 0 or \
539                    len(self.signalManager.getLinks(self, None, \
540                        "Unselected Items", None)) > 0 or \
541                            len(self.signalManager.getLinks(self, None, \
542                                "Selected Network", None)) > 0:
543
544                # signal connected
545                selected_nodes = self.networkCanvas.selected_nodes()
546                graph = self.graph_base.subgraph(selected_nodes)
547
548                if graph is not None:
549                    self.send("Selected Items", graph.items())
550
551                    if len(self.signalManager.getLinks(self, None, \
552                                                "Unselected Items", None)) > 0:
553                        nodes = self.networkCanvas.not_selected_nodes()
554                        if len(nodes) > 0 and self.graph_base.items() is not None:
555                            self.send("Other Items", self.graph_base.items().getitems(nodes))
556                        else:
557                            self.send("Other Items", None)
558
559                    self.send("Selected Network", graph)
560                else:
561                    self.send("Selected Items", None)
562                    self.send("Other Items", None)
563                    self.send("Selected Network", None)
564
565            if len(self.signalManager.getLinks(self, None, \
566                                "Selected Items Distance Matrix", None)) > 0:
567                # signal connected
568                matrix = None if self.items_matrix is None else self.items_matrix.getitems(selected_nodes)
569                self.send("Distance Matrix", matrix)
570
571        def send_marked_nodes(self):
572            if self.checkSendMarkedNodes and \
573                len(self.signalManager.getLinks(self, None, \
574                                                "Marked Items", None)) > 0:
575                # signal connected
576                markedNodes = self.networkCanvas.marked_nodes()
577
578                if len(markedNodes) > 0 and self.graph is not None and\
579                                         self.graph_base.items() is not None:
580
581                    items = self.graph_base.items().getitems(markedNodes)
582                    self.send("Marked Items", items)
583                else:
584                    self.send("Marked Items", None)
585
586        def _set_combos(self):
587            vars = self.graph_base.items_vars()
588            edgeVars = self.graph_base.links_vars()
589            lastLabelColumns = self.lastLabelColumns
590            lastTooltipColumns = self.lastTooltipColumns
591
592            self._clear_combos()
593
594            self.attributes = [(var.name, var.varType) for var in vars]
595            self.edgeAttributes = [(var.name, var.varType) for var in edgeVars]
596
597            for var in vars:
598                if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
599                    self.colorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
600
601                if var.varType in [Orange.data.Type.String] and hasattr(self.graph, 'items') and self.graph_base.items() is not None and len(self.graph_base.items()) > 0:
602
603                    value = self.graph_base.items()[0][var].value
604
605                    # can value be a list?
606                    try:
607                        if type(eval(value)) == type([]):
608                            self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
609                            continue
610                    except:
611                        pass
612
613                    if len(value.split(',')) > 1:
614                        self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), "num of " + unicode(var.name))
615
616                elif var.varType in [Orange.data.Type.Continuous]:
617                    self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
618
619                self.nameComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
620                self.showComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
621                self.editCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
622                self.comboAttSelection.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
623
624            for var in edgeVars:
625                if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
626                    self.edgeColorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
627
628            for i in range(self.vertexSizeCombo.count()):
629                if self.lastVertexSizeColumn == self.vertexSizeCombo.itemText(i):
630                    self.vertexSize = i
631                    break
632
633            for i in range(self.colorCombo.count()):
634                if self.lastColorColumn == self.colorCombo.itemText(i):
635                    self.color = i
636                    break
637
638            for i in range(self.attListBox.count()):
639                if str(self.attListBox.item(i).text()) in lastLabelColumns:
640                    self.attListBox.item(i).setSelected(1)
641
642            for i in range(self.tooltipListBox.count()):
643                if str(self.tooltipListBox.item(i).text()) in lastTooltipColumns:
644                    self.tooltipListBox.item(i).setSelected(1)
645
646            self.lastLabelColumns = lastLabelColumns
647            self.lastTooltipColumns = lastTooltipColumns
648
649        def _clear_combos(self):
650            self.attributes = []
651            self.edgeAttributes = []
652
653            self.colorCombo.clear()
654            self.vertexSizeCombo.clear()
655            self.nameComponentCombo.clear()
656            self.showComponentCombo.clear()
657            self.edgeColorCombo.clear()
658            self.editCombo.clear()
659            self.comboAttSelection.clear()
660
661            self.colorCombo.addItem("(same color)")
662            self.edgeColorCombo.addItem("(same color)")
663            self.vertexSizeCombo.addItem("(same size)")
664            self.nameComponentCombo.addItem("Select attribute")
665            self.showComponentCombo.addItem("Select attribute")
666            self.editCombo.addItem("Select attribute")
667            self.comboAttSelection.addItem("Select attribute")
668
669        def compute_network_info(self):
670            self.nShown = self.graph.number_of_nodes()
671
672            if self.graph.number_of_edges() > 0:
673                self.verticesPerEdge = float(self.graph.number_of_nodes()) / float(self.graph.number_of_edges())
674            else:
675                self.verticesPerEdge = 0
676
677            if self.graph.number_of_nodes() > 0:
678                self.edgesPerVertex = float(self.graph.number_of_edges()) / float(self.graph.number_of_nodes())
679            else:
680                self.edgesPerVertex = 0
681
682        def change_graph(self, newgraph):
683            self.information()
684
685            # if graph has more nodes and edges than pixels in 1600x1200 display,
686            # it is too big to visualize!
687            if newgraph.number_of_nodes() + newgraph.number_of_edges() > 50000:
688                self.information('New graph is too big to visualize. Keeping the old graph.')
689                return
690
691            self.graph = newgraph
692
693            self.number_of_nodes_label = self.graph.number_of_nodes()
694            self.number_of_edges_label = self.graph.number_of_edges()
695
696            if not self.networkCanvas.change_graph(self.graph):
697                return
698
699            self.compute_network_info()
700
701            if self.graph.number_of_nodes() > 0:
702                t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
703                self.frSteps = int(2.0 / t)
704                if self.frSteps < 1: self.frSteps = 1
705                if self.frSteps > 100: self.frSteps = 100
706    #       
707    #        if self.frSteps < 10:
708    #            self.networkCanvas.use_antialiasing = 0
709    #            self.networkCanvas.use_animations = 0
710    #            self.minVertexSize = 5
711    #            self.maxVertexSize = 5
712    #            self.maxLinkSize = 1
713    #            self.optMethod = 0
714    #            self.graph_layout_method()
715
716            animation_enabled = self.networkCanvas.animate_points;
717            self.networkCanvas.animate_points = False;
718
719            self.set_node_sizes()
720            self.set_node_colors()
721            self.set_edge_sizes()
722            self.set_edge_colors()
723
724            self._clicked_att_lstbox()
725            self._clicked_tooltip_lstbox()
726            self._clicked_edge_label_listbox()
727
728            self.networkCanvas.replot()
729
730            self.networkCanvas.animate_points = animation_enabled
731            qApp.processEvents()
732            self.networkCanvas.networkCurve.layout_fr(100, weighted=False, smooth_cooling=True)
733            self.networkCanvas.update_canvas()
734
735        def set_graph_none(self):
736            self.graph = None
737            #self.graph_base = None
738            self._clear_combos()
739            self.number_of_nodes_label = -1
740            self.number_of_edges_label = -1
741            self._items = None
742            self._links = None
743            self.set_items_distance_matrix(None)
744            self.networkCanvas.set_graph(None)
745
746        def set_graph(self, graph, curve=None):
747            self.information()
748            self.warning()
749            self.error()
750
751            if graph is None:
752                self.set_graph_none()
753                return
754
755            if graph.number_of_nodes() < 2:
756                self.set_graph_none()
757                self.information('I\'m not really in a mood to visualize just one node. Try again tomorrow.')
758                return
759
760            if graph == self.graph_base and self.graph is not None and self._network_view is None:
761                self.set_items(graph.items())
762                return
763
764            self.graph_base = graph
765
766            if self._network_view is not None:
767                graph = self._network_view.init_network(graph)
768
769            self.graph = graph
770
771            # if graph has more nodes and edges than pixels in 1600x1200 display,
772            # it is too big to visualize!
773            if self.graph.number_of_nodes() + self.graph.number_of_edges() > 50000:
774                self.set_graph_none()
775                self.error('Graph is too big to visualize. Try using one of the network views.')
776                return
777
778            if self.items_matrix is not None and self.items_matrix.dim != self.graph_base.number_of_nodes():
779                self.set_items_distance_matrix(None)
780
781            self.number_of_nodes_label = self.graph.number_of_nodes()
782            self.number_of_edges_label = self.graph.number_of_edges()
783
784            self.networkCanvas.set_graph(self.graph, curve, items=self.graph_base.items(), links=self.graph_base.links())
785
786            if self._items is not None and 'x' in self._items.domain and 'y' in self._items.domain:
787                positions = dict((node, (self._items[node]['x'].value, self._items[node]['y'].value)) \
788                             for node in self.graph if self._items[node]['x'].value != '?' \
789                             and self._items[node]['y'].value != '?')
790
791                self.networkCanvas.networkCurve.set_node_coordinates(positions)
792
793
794            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
795            self.networkCanvas.maxEdgeSize = self.maxLinkSize
796            self.networkCanvas.minComponentEdgeWidth = self.minComponentEdgeWidth
797            self.networkCanvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
798            self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)
799
800            self.compute_network_info()
801            self._set_combos()
802
803            lastNameComponentAttributeFound = False
804            for i in range(self.nameComponentCombo.count()):
805                if self.lastNameComponentAttribute == self.nameComponentCombo.itemText(i):
806                    lastNameComponentAttributeFound = True
807                    self.nameComponentAttribute = i
808                    self.nameComponents()
809                    self.showComponentAttribute = self.showComponentCombo.count() - 1
810                    self.showComponents()
811                    break
812
813            if not lastNameComponentAttributeFound:
814                self.lastNameComponentAttribute = ''
815
816            self.showComponentAttribute = None
817
818            t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
819            self.frSteps = int(2.0 / t)
820            if self.frSteps < 1: self.frSteps = 1
821            if self.frSteps > 100: self.frSteps = 100
822
823            # if graph is large, set random layout, min vertex size, min edge size
824            if self.frSteps < 10:
825                self.networkCanvas.update_antialiasing(False)
826                self.networkCanvas.update_animations(False)
827                self.minVertexSize = 5
828                self.maxVertexSize = 5
829                self.maxLinkSize = 1
830                self.optMethod = 0
831                self.graph_layout_method()
832
833            self.networkCanvas.labelsOnMarkedOnly = self.labelsOnMarkedOnly
834            self.networkCanvas.showWeights = self.showWeights
835
836            self.set_node_sizes()
837            self.set_node_colors()
838            self.set_edge_sizes()
839            self.set_edge_colors()
840
841            self._clicked_att_lstbox()
842            self._clicked_tooltip_lstbox()
843            self._clicked_edge_label_listbox()
844
845            self.optButton.setChecked(1)
846            self.graph_layout()
847
848        def set_network_view(self, nxView):
849            self.error()
850            self.warning()
851            self.information()
852
853            if self.graph is None:
854                self.information('Do not forget to add a graph!')
855
856            if self._network_view is not None:
857                QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
858
859            self._network_view = nxView
860
861            if self._network_view is not None:
862                self._network_view.set_nx_explorer(self)
863
864            self.set_graph(self.graph_base)
865
866            if self._network_view is not None:
867                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
868
869        def set_items(self, items=None):
870            self.error()
871            self.warning()
872            self.information()
873
874            if items is None:
875                return
876
877            if self.graph is None:
878                self.warning('No graph found!')
879                return
880
881            if len(items) != self.graph_base.number_of_nodes():
882                self.error('ExampleTable items must have one example for each vertex.')
883                return
884
885            self.graph_base.set_items(items)
886
887            self.set_node_sizes()
888            self.networkCanvas.items = items
889            self.networkCanvas.showWeights = self.showWeights
890            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
891            self._set_combos()
892            #self.networkCanvas.updateData()
893
894        def mark_items(self, items):
895            self.markInputCombo.clear()
896            self.markInputRadioButton.setEnabled(False)
897            self.markInputItems = items
898
899            self.error()
900            self.warning()
901            self.information()
902
903            if items is None:
904                return
905
906            if self.graph is None or self.graph_base.items() is None or items is None:
907                self.warning('No graph found or no items attached to the graph.')
908                return
909
910            if len(items) > 0:
911                lstOrgDomain = [x.name for x in self.graph_base.items().domain] + [self.graph_base.items().domain[x].name for x in self.graph_base.items().domain.getmetas()]
912                lstNewDomain = [x.name for x in items.domain] + [items.domain[x].name for x in items.domain.getmetas()]
913                commonVars = set(lstNewDomain) & set(lstOrgDomain)
914
915                self.markInputCombo.addItem(self.icons[Orange.data.Type.Discrete], unicode("ID"))
916
917                if len(commonVars) > 0:
918                    for var in commonVars:
919                        orgVar = self.graph_base.items().domain[var]
920                        mrkVar = items.domain[var]
921
922                        if orgVar.varType == mrkVar.varType and orgVar.varType == Orange.data.Type.String:
923                            self.markInputCombo.addItem(self.icons[orgVar.varType], unicode(orgVar.name))
924
925                self.markInputRadioButton.setEnabled(True)
926                self.set_mark_mode(9)
927
928        def set_explore_distances(self):
929            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
930
931            if self.explore_distances:
932                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
933
934        def explore_focused(self):
935            sel = self.networkCanvas.selected_nodes()
936            if len(sel) == 1:
937                ndx_1 = sel[0]
938                self.networkCanvas.label_distances = [['%.2f' % \
939                                self.items_matrix[ndx_1][ndx_2]] \
940                                for ndx_2 in self.networkCanvas.graph.nodes()]
941            else:
942                self.networkCanvas.label_distances = None
943
944            self.networkCanvas.set_node_labels(self.lastLabelColumns)
945            self.networkCanvas.replot()
946
947        #######################################################################
948        ### Layout Optimization                                             ###
949        #######################################################################
950
951        def graph_layout(self):
952            if self.graph is None or self.graph.number_of_nodes <= 0:   #grafa se ni
953                self.optButton.setChecked(False)
954                return
955
956            if not self.optButton.isChecked() and not self.optMethod in [2, 3, 9, 10]:
957                self.optButton.setChecked(False)
958                return
959
960            qApp.processEvents()
961
962            if self.optMethod == 1:
963                self.networkCanvas.networkCurve.random()
964            elif self.optMethod == 2:
965                self.graph_layout_fr(False)
966            elif self.optMethod == 3:
967                self.graph_layout_fr(True)
968            elif self.optMethod == 4:
969                self.graph_layout_fr_radial()
970            elif self.optMethod == 5:
971                self.networkCanvas.networkCurve.circular(\
972                                            NetworkCurve.circular_crossing)
973            elif self.optMethod == 6:
974                self.networkCanvas.networkCurve.circular(\
975                                            NetworkCurve.circular_original)
976            elif self.optMethod == 7:
977                self.networkCanvas.networkCurve.circular(\
978                                            NetworkCurve.circular_random)
979            elif self.optMethod == 8:
980                self.graph_layout_fragviz()
981            elif self.optMethod == 9:
982                self.graph_layout_mds()
983            elif self.optMethod == 10:
984                self.graph_layout_pivot_mds()
985
986            self.optButton.setChecked(False)
987            self.networkCanvas.update_canvas()
988
989        def graph_layout_method(self, method=None):
990            self.information()
991            self.stepsSpin.label.setText('Iterations: ')
992            self.optButton.setEnabled(True)
993            self.cb_opt_from_curr.setEnabled(False)
994
995            if method is not None:
996                self.optMethod = method
997
998            if str(self.optMethod) == '0':
999                self.optButton.setEnabled(False)
1000            else:
1001                self.optButton.setEnabled(True)
1002
1003            if str(self.optMethod) in ['2', '3', '4']:
1004                self.stepsSpin.setEnabled(True)
1005
1006            elif str(self.optMethod) in ['8', '9', '10']:
1007                if str(self.optMethod) == '8':
1008                    self.stepsSpin.label.setText('Pivots: ')
1009
1010                if str(self.optMethod) in ['9', '10']:
1011                    self.cb_opt_from_curr.setEnabled(True)
1012
1013                self.stepsSpin.setEnabled(True)
1014
1015                if self.items_matrix is None:
1016                    self.information('Set distance matrix to input signal')
1017                    self.optButton.setEnabled(False)
1018                    return
1019                if self.graph is None:
1020                    self.information('No network found')
1021                    self.optButton.setEnabled(False)
1022                    return
1023                if self.items_matrix.dim != self.graph.number_of_nodes():
1024                    self.error('Distance matrix dimensionality must equal number of vertices')
1025                    self.optButton.setEnabled(False)
1026                    return
1027            else:
1028                self.stepsSpin.setEnabled(False)
1029                self.optButton.setChecked(True)
1030                self.graph_layout()
1031
1032        def mds_progress(self, avgStress, stepCount):
1033            #self.drawForce()
1034
1035            #self.mdsInfoA.setText("Avg. Stress: %.20f" % avgStress)
1036            #self.mdsInfoB.setText("Num. steps: %i" % stepCount)
1037            self.progressBarSet(int(stepCount * 100 / self.frSteps))
1038            qApp.processEvents()
1039
1040        def graph_layout_fragviz(self):
1041            if self.items_matrix is None:
1042                self.information('Set distance matrix to input signal')
1043                self.optButton.setChecked(False)
1044                return
1045
1046            if self.layout is None:
1047                self.information('No network found')
1048                self.optButton.setChecked(False)
1049                return
1050
1051            if self.items_matrix.dim != self.graph.number_of_nodes():
1052                self.error('Distance matrix dimensionality must equal number of vertices')
1053                self.optButton.setChecked(False)
1054                return
1055
1056            if not self.optButton.isChecked():
1057                self.networkCanvas.networkCurve.stopMDS = True
1058                self.optButton.setChecked(False)
1059                self.optButton.setText("Optimize layout")
1060                return
1061
1062            self.optButton.setText("Stop")
1063            self.progressBarInit()
1064            qApp.processEvents()
1065
1066            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1067                matrix = self.items_matrix
1068            else:
1069                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1070
1071            self.networkCanvas.networkCurve.layout_fragviz(self.frSteps, matrix, self.graph, self.mds_progress, self.opt_from_curr)
1072
1073            self.optButton.setChecked(False)
1074            self.optButton.setText("Optimize layout")
1075            self.progressBarFinished()
1076
1077        def graph_layout_mds(self):
1078            if self.items_matrix is None:
1079                self.information('Set distance matrix to input signal')
1080                self.optButton.setChecked(False)
1081                return
1082
1083            if self.layout is None:
1084                self.information('No network found')
1085                self.optButton.setChecked(False)
1086                return
1087
1088            if self.items_matrix.dim != self.graph.number_of_nodes():
1089                self.error('Distance matrix dimensionality must equal number of vertices')
1090                self.optButton.setChecked(False)
1091                return
1092
1093            if not self.optButton.isChecked():
1094                self.networkCanvas.networkCurve.stopMDS = True
1095                self.optButton.setChecked(False)
1096                self.optButton.setText("Optimize layout")
1097                return
1098
1099            self.optButton.setText("Stop")
1100            self.progressBarInit()
1101            qApp.processEvents()
1102
1103            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1104                matrix = self.items_matrix
1105            else:
1106                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1107
1108            self.networkCanvas.networkCurve.layout_mds(self.frSteps, matrix, self.mds_progress, self.opt_from_curr)
1109
1110            self.optButton.setChecked(False)
1111            self.optButton.setText("Optimize layout")
1112            self.progressBarFinished()
1113
1114        def graph_layout_fr(self, weighted):
1115            if self.graph is None:
1116                return
1117
1118            if not self.optButton.isChecked():
1119                self.networkCanvas.networkCurve.stop_optimization()
1120                self.optButton.setChecked(False)
1121                self.optButton.setText("Optimize layout")
1122                return
1123
1124            self.optButton.setText("Stop")
1125            qApp.processEvents()
1126            self.networkCanvas.networkCurve.layout_fr(self.frSteps, False)
1127            self.networkCanvas.update_canvas()
1128            self.optButton.setChecked(False)
1129            self.optButton.setText("Optimize layout")
1130
1131        def graph_layout_fr_radial(self):
1132            if self.graph is None:   #grafa se ni
1133                return
1134
1135    #        #print "F-R Radial"
1136    #        k = 1.13850193174e-008
1137    #        nodes = self.graph.number_of_nodes()
1138    #        t = k * nodes * nodes
1139    #        refreshRate = int(5.0 / t)
1140    #        if refreshRate <    1: refreshRate = 1
1141    #        if refreshRate > 1500: refreshRate = 1500
1142    #        #print "refreshRate: " + str(refreshRate)
1143    #       
1144    #        tolerance = 5
1145    #        initTemp = 100
1146    #        centerNdx = 0
1147    #       
1148    #        selection = self.networkCanvas.getSelection()
1149    #        if len(selection) > 0:
1150    #            centerNdx = selection[0]
1151    #           
1152    #        #print "center ndx: " + str(centerNdx)
1153    #        initTemp = self.layout.fr_radial(centerNdx, refreshRate, initTemp)
1154    #        self.networkCanvas.circles = [10000 / 12, 10000/12*2, 10000/12*3]#, 10000/12*4, 10000/12*5]
1155    #        #self.networkCanvas.circles = [100, 200, 300]
1156    #        self.networkCanvas.updateCanvas()
1157    #        self.networkCanvas.circles = []
1158
1159        def graph_layout_pivot_mds(self):
1160            self.information()
1161
1162            if self.items_matrix is None:
1163                self.information('Set distance matrix to input signal')
1164                return
1165
1166            if self.graph_base is None:
1167                self.information('No network found')
1168                return
1169
1170            if self.items_matrix.dim != self.graph_base.number_of_nodes():
1171                self.error('The number of vertices does not match matrix size.')
1172                return
1173
1174            self.frSteps = min(self.frSteps, self.graph.number_of_nodes())
1175            qApp.processEvents()
1176
1177            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1178                matrix = self.items_matrix
1179            else:
1180                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1181
1182            mds = orngMDS.PivotMDS(matrix, self.frSteps)
1183            x, y = mds.optimize()
1184            xy = zip(list(x), list(y))
1185            coors = dict(zip(sorted(self.graph.nodes()), xy))
1186            self.networkCanvas.networkCurve.set_node_coordinates(coors)
1187            self.networkCanvas.update_canvas()
1188
1189        #######################################################################
1190        ### Network Visualization                                           ###
1191        #######################################################################
1192
1193        def _set_colors(self):
1194            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
1195            if dlg.exec_():
1196                self.colorSettings = dlg.getColorSchemas()
1197                self.selectedSchemaIndex = dlg.selectedSchemaIndex
1198                self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
1199                self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
1200
1201                self.set_node_colors()
1202
1203        def _set_edge_color_palette(self):
1204            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
1205            if dlg.exec_():
1206                self.edgeColorSettings = dlg.getColorSchemas()
1207                self.selectedEdgeSchemaIndex = dlg.selectedSchemaIndex
1208                self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
1209                self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
1210
1211                self.set_edge_colors()
1212
1213        def _create_color_dialog(self, colorSettings, selectedSchemaIndex):
1214            c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
1215            c.createDiscretePalette("discPalette", "Discrete Palette")
1216            c.createContinuousPalette("contPalette", "Continuous Palette")
1217            c.setColorSchemas(colorSettings, selectedSchemaIndex)
1218            return c
1219
1220        def _clicked_att_lstbox(self):
1221            if self.graph is None:
1222                return
1223
1224            self.lastLabelColumns = [self.attributes[i][0] for i in self.markerAttributes]
1225            self.networkCanvas.set_node_labels(self.lastLabelColumns)
1226            self.networkCanvas.replot()
1227
1228        def _clicked_tooltip_lstbox(self):
1229            if self.graph is None:
1230                return
1231
1232            self.lastTooltipColumns = [self.attributes[i][0] for i in self.tooltipAttributes]
1233            self.networkCanvas.set_tooltip_attributes(self.lastTooltipColumns)
1234            self.networkCanvas.replot()
1235
1236        def _clicked_edge_label_listbox(self):
1237            if self.graph is None:
1238                return
1239
1240            self.lastEdgeLabelAttributes = set([self.edgeAttributes[i][0] for i in self.edgeLabelAttributes])
1241            self.networkCanvas.set_edge_labels(self.lastEdgeLabelAttributes)
1242            self.networkCanvas.replot()
1243
1244        def set_node_colors(self):
1245            if self.graph is None:
1246                return
1247
1248            self.networkCanvas.set_node_colors(self.colorCombo.currentText())
1249            self.lastColorColumn = self.colorCombo.currentText()
1250
1251        def set_edge_colors(self):
1252            if self.graph is None:
1253                return
1254
1255            self.networkCanvas.set_edge_colors(self.edgeColorCombo.currentText())
1256            self.lastEdgeColorColumn = self.edgeColorCombo.currentText()
1257
1258        def set_edge_sizes(self):
1259            if self.graph is None:
1260                return
1261
1262            self.networkCanvas.networkCurve.set_edge_sizes(self.maxLinkSize)
1263            self.networkCanvas.replot()
1264
1265        def set_node_sizes(self):
1266            if self.graph is None or self.networkCanvas is None:
1267                return
1268
1269            if self.minVertexSize > self.maxVertexSize:
1270                self.maxVertexSize = self.minVertexSize
1271
1272            items = self.graph_base.items()
1273
1274            if items is None:
1275                self.networkCanvas.networkCurve.set_node_sizes({}, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1276                return
1277
1278            self.lastVertexSizeColumn = self.vertexSizeCombo.currentText()
1279            column = str(self.vertexSizeCombo.currentText())
1280
1281            values = {}
1282            if column in items.domain or (column.startswith("num of ") and column.replace("num of ", "") in items.domain):
1283                if column in items.domain:
1284                    values = dict((x, items[x][column].value) for x in self.graph if not items[x][column].isSpecial())
1285                else:
1286                    values = dict((x, len(items[x][column.replace("num of ", "")].value.split(','))) for x in self.graph)
1287
1288            if len(values) == 0:
1289                values = dict((node, 1.) for node in self.graph)
1290
1291            if self.invertSize:
1292                maxval = max(values.itervalues())
1293                values.update((key, maxval - val) for key, val in values.iteritems())
1294                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1295            else:
1296                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1297
1298            self.networkCanvas.replot()
1299
1300        def set_font(self):
1301            if self.networkCanvas is None:
1302                return
1303
1304            weights = {0: 50, 1: 80}
1305
1306            font = self.networkCanvas.font()
1307            font.setPointSize(self.fontSize)
1308            font.setWeight(weights[self.fontWeight])
1309            self.networkCanvas.setFont(font)
1310            self.networkCanvas.fontSize = font
1311            self.networkCanvas.set_node_labels()
1312
1313        def sendReport(self):
1314            self.reportSettings("Graph data",
1315                                [("Number of vertices", self.graph.number_of_nodes()),
1316                                 ("Number of edges", self.graph.number_of_edges()),
1317                                 ("Vertices per edge", "%.3f" % self.verticesPerEdge),
1318                                 ("Edges per vertex", "%.3f" % self.edgesPerVertex),
1319                                 ])
1320            if self.color or self.vertexSize or self.markerAttributes or self.edgeColor:
1321                self.reportSettings("Visual settings",
1322                                    [self.color and ("Vertex color", self.colorCombo.currentText()),
1323                                     self.vertexSize and ("Vertex size", str(self.vertexSizeCombo.currentText()) + " (inverted)" if self.invertSize else ""),
1324                                     self.markerAttributes and ("Labels", ", ".join(self.attributes[i][0] for i in self.markerAttributes)),
1325                                     self.edgeColor and ("Edge colors", self.edgeColorCombo.currentText()),
1326                                    ])
1327            self.reportSettings("Optimization",
1328                                [("Method", self.optCombo.currentText()),
1329                                 ("Iterations", self.frSteps)])
1330            self.reportSection("Graph")
1331            self.reportImage(self.networkCanvas.saveToFileDirect)
1332
1333        #######################################################################
1334        ### PROTOTYPE                                                       ###
1335        #######################################################################
1336
1337        def set_component_edge_width(self, changedMin=True):
1338            if self.networkCanvas is None:
1339                return
1340
1341            canvas = self.networkCanvas
1342            if changedMin:
1343                if self.maxComponentEdgeWidth < self.minComponentEdgeWidth:
1344                    self.maxComponentEdgeWidth = self.minComponentEdgeWidth
1345            else:
1346                if self.minComponentEdgeWidth > self.maxComponentEdgeWidth:
1347                    self.minComponentEdgeWidth = self.maxComponentEdgeWidth
1348
1349            canvas.minComponentEdgeWidth = self.minComponentEdgeWidth
1350            canvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
1351            self.networkCanvas.updateCanvas()
1352
1353        def showComponents(self):
1354            if self.graph is None or self.graph_base.items() is None:
1355                return
1356
1357            vars = [x.name for x in self.graph_base.items_vars()]
1358
1359            if not self.showComponentCombo.currentText() in vars:
1360                self.networkCanvas.showComponentAttribute = None
1361                self.lastNameComponentAttribute = ''
1362            else:
1363                self.networkCanvas.showComponentAttribute = self.showComponentCombo.currentText()
1364
1365            self.networkCanvas.drawComponentKeywords()
1366
1367        def nameComponents(self):
1368            """Names connected components of genes according to GO terms."""
1369            self.progressBarFinished()
1370            self.lastNameComponentAttribute = None
1371
1372            if self.graph is None or self.graph_base.items() is None:
1373                return
1374
1375            vars = [x.name for x in self.graph_base.items_vars()]
1376            if not self.nameComponentCombo.currentText() in vars:
1377                return
1378
1379            self.progressBarInit()
1380            components = [c for c in Orange.network.nx.algorithms.components.connected_components(self.graph) if len(c) > 1]
1381            if 'component name' in self.graph_base.items().domain:
1382                keyword_table = self.graph_base.items()
1383            else:
1384                keyword_table = Orange.data.Table(Orange.data.Domain(Orange.data.variable.String('component name')), [[''] for i in range(len(self.graph_base.items()))])
1385
1386            import obiGO
1387            ontology = obiGO.Ontology.Load(progressCallback=self.progressBarSet)
1388            annotations = obiGO.Annotations.Load(self.organism, ontology=ontology, progressCallback=self.progressBarSet)
1389
1390            allGenes = set([e[str(self.nameComponentCombo.currentText())].value for e in self.graph_base.items()])
1391            foundGenesets = False
1392            if len(annotations.geneNames & allGenes) < 1:
1393                allGenes = set(reduce(operator.add, [e[str(self.nameComponentCombo.currentText())].value.split(', ') for e in self.graph_base.items()]))
1394                if len(annotations.geneNames & allGenes) < 1:
1395                    self.warning('no genes found')
1396                    return
1397                else:
1398                    foundGenesets = True
1399
1400            def rank(a, j, reverse=False):
1401                if len(a) <= 0: return
1402
1403                if reverse:
1404                    a.sort(lambda x, y: 1 if x[j] > y[j] else -1 if x[j] < y[j] else 0)
1405                    top_value = a[0][j]
1406                    top_rank = len(a)
1407                    max_rank = float(len(a))
1408                    int_ndx = 0
1409                    for k in range(len(a)):
1410                        if top_value < a[k][j]:
1411                            top_value = a[k][j]
1412                            if k - int_ndx > 1:
1413                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1414                                for l in range(int_ndx, k):
1415                                    a[l][j] = avg_rank
1416
1417                            int_ndx = k
1418
1419                        a[k][j] = top_rank / max_rank
1420                        top_rank -= 1
1421
1422                    k += 1
1423                    if k - int_ndx > 1:
1424                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1425                        for l in range(int_ndx, k):
1426                            a[l][j] = avg_rank
1427
1428                else:
1429                    a.sort(lambda x, y: 1 if x[j] < y[j] else -1 if x[j] > y[j] else 0)
1430                    top_value = a[0][j]
1431                    top_rank = len(a)
1432                    max_rank = float(len(a))
1433                    int_ndx = 0
1434                    for k in range(len(a)):
1435                        if top_value > a[k][j]:
1436                            top_value = a[k][j]
1437                            if k - int_ndx > 1:
1438                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1439                                for l in range(int_ndx, k):
1440                                    a[l][j] = avg_rank
1441
1442                            int_ndx = k
1443
1444                        a[k][j] = top_rank / max_rank
1445                        top_rank -= 1
1446
1447                    k += 1
1448                    if k - int_ndx > 1:
1449                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1450                        for l in range(int_ndx, k):
1451                            a[l][j] = avg_rank
1452
1453            for i in range(len(components)):
1454                component = components[i]
1455                if len(component) <= 1:
1456                    continue
1457
1458                if foundGenesets:
1459                    genes = reduce(operator.add, [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value.split(', ') for v in component])
1460                else:
1461                    genes = [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value for v in component]
1462
1463                res1 = annotations.GetEnrichedTerms(genes, aspect="P")
1464                res2 = annotations.GetEnrichedTerms(genes, aspect="F")
1465                res = res1.items() + res2.items()
1466                #namingScore = [[(1-p_value) * (float(len(g)) / len(genes)) / (float(ref) / len(annotations.geneNames)), ontology.terms[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res.items() if p_value < 0.1]
1467                #namingScore = [[(1-p_value) * len(g) / ref, ontology.terms[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res.items() if p_value < 0.1]
1468
1469                namingScore = [[len(g), ref, p_value, ontology[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res if p_value < 0.1]
1470                if len(namingScore) == 0:
1471                    continue
1472
1473                annotated_genes = max([a[0] for a in namingScore])
1474
1475                rank(namingScore, 1, reverse=True)
1476                rank(namingScore, 2, reverse=True)
1477                rank(namingScore, 0)
1478
1479                namingScore = [[10 * rank_genes + 0.5 * rank_ref + rank_p_value, name, g, ref, p_value] for rank_genes, rank_ref, rank_p_value, name, g, ref, p_value in namingScore]
1480                namingScore.sort(reverse=True)
1481
1482                if len(namingScore) < 1:
1483                    print "warning. no annotations found for group of genes: " + ", ".join(genes)
1484                    continue
1485                elif len(namingScore[0]) < 2:
1486                    print "warning. error computing score for group of genes: " + ", ".join(genes)
1487                    continue
1488
1489                for v in component:
1490                    name = str(namingScore[0][1])
1491                    attrs = "%d/%d, %d, %lf" % (namingScore[0][2], annotated_genes, namingScore[0][3], namingScore[0][4])
1492                    info = ''
1493                    if self.showTextMiningInfo:
1494                        info = "\n" + attrs + "\n" + str(namingScore[0][0])
1495                    keyword_table[v]['component name'] = name + info
1496
1497                self.progressBarSet(i * 100.0 / len(components))
1498
1499            self.lastNameComponentAttribute = self.nameComponentCombo.currentText()
1500            self.set_items(Orange.data.Table([self.graph_base.items(), keyword_table]))
1501            self.progressBarFinished()
1502
1503
1504        def setAutoSendAttributes(self):
1505            print 'TODO setAutoSendAttributes'
1506            #if self.autoSendAttributes:
1507            #    self.networkCanvas.callbackSelectVertex = self.sendAttSelectionList
1508            #else:
1509            #    self.networkCanvas.callbackSelectVertex = None
1510
1511        def sendAttSelectionList(self):
1512            if not self.graph is None:
1513                vars = [x.name for x in self.graph_base.links_vars()]
1514                if not self.comboAttSelection.currentText() in vars:
1515                    return
1516                att = str(self.comboAttSelection.currentText())
1517                vertices = self.networkCanvas.selected_nodes()
1518
1519                if len(vertices) != 1:
1520                    return
1521
1522                attributes = str(self.graph_base.items()[vertices[0]][att]).split(', ')
1523            else:
1524                attributes = None
1525            self.send("Features", attributes)
1526
1527
1528except ImportError as err:
1529    try:
1530        from OWNxCanvas import *
1531    except:
1532        # if Qwt is also not installed throw could not import orangeqt error
1533        raise err
1534
1535    from OWNxExplorerQwt import OWNxExplorerQwt as OWNxExplorer
1536
1537if __name__ == "__main__":
1538    a = QApplication(sys.argv)
1539    ow = OWNxExplorer()
1540    ow.show()
1541
1542    def setNetwork(signal, data, id=None):
1543        if signal == 'Network':
1544            ow.set_graph(data)
1545        #if signal == 'Items':
1546        #    ow.set_items(data)
1547
1548    import OWNxFile
1549    owFile = OWNxFile.OWNxFile()
1550    owFile.send = setNetwork
1551    owFile.show()
1552    owFile.selectNetFile(0)
1553
1554    a.exec_()
1555    ow.saveSettings()
1556    owFile.saveSettings()
Note: See TracBrowser for help on using the repository browser.