source: orange/orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 9631:3e3c02fa1b23

Revision 9631:3e3c02fa1b23, 73.5 KB checked in by Miha Stajdohar <miha.stajdohar@…>, 2 years ago (diff)

Refresh node attributes on new data table items.

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', \
520                '', 'NetworkX graph as Python pickle (*.gpickle)\nPajek ' + \
521                'network (*.net)\nGML network (*.gml)')
522            if filename:
523                fn = ""
524                head, tail = os.path.splitext(str(filename))
525                if not tail:
526                    fn = head + ".net"
527                else:
528                    fn = str(filename)
529
530                items = self.graph.items()
531                for i in range(self.graph.number_of_nodes()):
532                    graph_node = self.graph.node[i]
533                    plot_node = self.networkCanvas.networkCurve.nodes()[i]
534
535                    if items is not None:
536                        ex = items[i]
537                        if 'x' in ex.domain:
538                            ex['x'] = plot_node.x()
539                        if 'y' in ex.domain:
540                            ex['y'] = plot_node.y()
541
542                    graph_node['x'] = plot_node.x()
543                    graph_node['y'] = plot_node.y()
544
545                Orange.network.readwrite.write(self.graph, fn)
546
547        def send_data(self):
548            if len(self.signalManager.getLinks(self, None, \
549                "Selected Items", None)) > 0 or \
550                    len(self.signalManager.getLinks(self, None, \
551                        "Unselected Items", None)) > 0 or \
552                            len(self.signalManager.getLinks(self, None, \
553                                "Selected Network", None)) > 0:
554
555                # signal connected
556                selected_nodes = self.networkCanvas.selected_nodes()
557                graph = self.graph_base.subgraph(selected_nodes)
558
559                if graph is not None:
560                    self.send("Selected Items", graph.items())
561
562                    if len(self.signalManager.getLinks(self, None, \
563                                                "Unselected Items", None)) > 0:
564                        nodes = self.networkCanvas.not_selected_nodes()
565                        if len(nodes) > 0 and self.graph_base.items() is not None:
566                            self.send("Other Items", self.graph_base.items().getitems(nodes))
567                        else:
568                            self.send("Other Items", None)
569
570                    self.send("Selected Network", graph)
571                else:
572                    self.send("Selected Items", None)
573                    self.send("Other Items", None)
574                    self.send("Selected Network", None)
575
576            if len(self.signalManager.getLinks(self, None, \
577                                "Selected Items Distance Matrix", None)) > 0:
578                # signal connected
579                matrix = None if self.items_matrix is None else self.items_matrix.getitems(selected_nodes)
580                self.send("Distance Matrix", matrix)
581
582        def send_marked_nodes(self):
583            if self.checkSendMarkedNodes and \
584                len(self.signalManager.getLinks(self, None, \
585                                                "Marked Items", None)) > 0:
586                # signal connected
587                markedNodes = self.networkCanvas.marked_nodes()
588
589                if len(markedNodes) > 0 and self.graph is not None and\
590                                         self.graph_base.items() is not None:
591
592                    items = self.graph_base.items().getitems(markedNodes)
593                    self.send("Marked Items", items)
594                else:
595                    self.send("Marked Items", None)
596
597        def _set_combos(self):
598            vars = self.graph_base.items_vars()
599            edgeVars = self.graph_base.links_vars()
600            lastLabelColumns = self.lastLabelColumns
601            lastTooltipColumns = self.lastTooltipColumns
602
603            self._clear_combos()
604
605            self.attributes = [(var.name, var.varType) for var in vars]
606            self.edgeAttributes = [(var.name, var.varType) for var in edgeVars]
607
608            for var in vars:
609                if var.varType in [Orange.data.Type.Discrete, \
610                                   Orange.data.Type.Continuous]:
611                    self.colorCombo.addItem(self.icons.get(var.varType, \
612                                            self.icons[-1]), unicode(var.name))
613
614                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:
615
616                    value = self.graph_base.items()[0][var].value
617
618                    # can value be a list?
619                    try:
620                        if type(eval(value)) == type([]):
621                            self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
622                            continue
623                    except:
624                        pass
625
626                    if len(value.split(',')) > 1:
627                        self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), "num of " + unicode(var.name))
628
629                elif var.varType in [Orange.data.Type.Continuous]:
630                    self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
631
632                self.nameComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
633                self.showComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
634                self.editCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
635                self.comboAttSelection.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
636
637            for var in edgeVars:
638                if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
639                    self.edgeColorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
640
641            for i in range(self.vertexSizeCombo.count()):
642                if self.lastVertexSizeColumn == \
643                        self.vertexSizeCombo.itemText(i):
644                    self.vertexSize = i
645                    self.set_node_sizes()
646                    break
647
648            for i in range(self.colorCombo.count()):
649                if self.lastColorColumn == self.colorCombo.itemText(i):
650                    self.color = i
651                    self.set_node_colors()
652                    break
653
654            for i in range(self.attListBox.count()):
655                if str(self.attListBox.item(i).text()) in lastLabelColumns:
656                    self.attListBox.item(i).setSelected(1)
657                self._clicked_att_lstbox()
658
659            for i in range(self.tooltipListBox.count()):
660                if str(self.tooltipListBox.item(i).text()) \
661                                                    in lastTooltipColumns:
662                    self.tooltipListBox.item(i).setSelected(1)
663                self._clicked_tooltip_lstbox()
664
665            self.lastLabelColumns = lastLabelColumns
666            self.lastTooltipColumns = lastTooltipColumns
667
668        def _clear_combos(self):
669            self.attributes = []
670            self.edgeAttributes = []
671
672            self.colorCombo.clear()
673            self.vertexSizeCombo.clear()
674            self.nameComponentCombo.clear()
675            self.showComponentCombo.clear()
676            self.edgeColorCombo.clear()
677            self.editCombo.clear()
678            self.comboAttSelection.clear()
679
680            self.colorCombo.addItem("(same color)")
681            self.edgeColorCombo.addItem("(same color)")
682            self.vertexSizeCombo.addItem("(same size)")
683            self.nameComponentCombo.addItem("Select attribute")
684            self.showComponentCombo.addItem("Select attribute")
685            self.editCombo.addItem("Select attribute")
686            self.comboAttSelection.addItem("Select attribute")
687
688        def compute_network_info(self):
689            self.nShown = self.graph.number_of_nodes()
690
691            if self.graph.number_of_edges() > 0:
692                self.verticesPerEdge = float(self.graph.number_of_nodes()) / float(self.graph.number_of_edges())
693            else:
694                self.verticesPerEdge = 0
695
696            if self.graph.number_of_nodes() > 0:
697                self.edgesPerVertex = float(self.graph.number_of_edges()) / float(self.graph.number_of_nodes())
698            else:
699                self.edgesPerVertex = 0
700
701        def change_graph(self, newgraph):
702            self.information()
703
704            # if graph has more nodes and edges than pixels in 1600x1200 display,
705            # it is too big to visualize!
706            if newgraph.number_of_nodes() + newgraph.number_of_edges() > 50000:
707                self.information('New graph is too big to visualize. Keeping the old graph.')
708                return
709
710            self.graph = newgraph
711
712            self.number_of_nodes_label = self.graph.number_of_nodes()
713            self.number_of_edges_label = self.graph.number_of_edges()
714
715            if not self.networkCanvas.change_graph(self.graph):
716                return
717
718            self.compute_network_info()
719
720            if self.graph.number_of_nodes() > 0:
721                t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
722                self.frSteps = int(2.0 / t)
723                if self.frSteps < 1: self.frSteps = 1
724                if self.frSteps > 100: self.frSteps = 100
725    #       
726    #        if self.frSteps < 10:
727    #            self.networkCanvas.use_antialiasing = 0
728    #            self.networkCanvas.use_animations = 0
729    #            self.minVertexSize = 5
730    #            self.maxVertexSize = 5
731    #            self.maxLinkSize = 1
732    #            self.optMethod = 0
733    #            self.graph_layout_method()
734
735            animation_enabled = self.networkCanvas.animate_points;
736            self.networkCanvas.animate_points = False;
737
738            self.set_node_sizes()
739            self.set_node_colors()
740            self.set_edge_sizes()
741            self.set_edge_colors()
742
743            self._clicked_att_lstbox()
744            self._clicked_tooltip_lstbox()
745            self._clicked_edge_label_listbox()
746
747            self.networkCanvas.replot()
748
749            self.networkCanvas.animate_points = animation_enabled
750            qApp.processEvents()
751            self.networkCanvas.networkCurve.layout_fr(100, weighted=False, smooth_cooling=True)
752            self.networkCanvas.update_canvas()
753
754        def set_graph_none(self):
755            self.graph = None
756            #self.graph_base = None
757            self._clear_combos()
758            self.number_of_nodes_label = -1
759            self.number_of_edges_label = -1
760            self._items = None
761            self._links = None
762            self.set_items_distance_matrix(None)
763            self.networkCanvas.set_graph(None)
764
765        def set_graph(self, graph, curve=None):
766            self.information()
767            self.warning()
768            self.error()
769
770            if graph is None:
771                self.set_graph_none()
772                return
773
774            if graph.number_of_nodes() < 2:
775                self.set_graph_none()
776                self.information('I\'m not really in a mood to visualize just one node. Try again tomorrow.')
777                return
778
779            if graph == self.graph_base and self.graph is not None and \
780                                                    self._network_view is None:
781                self.set_items(graph.items())
782                return
783
784            self.graph_base = graph
785
786            if self._network_view is not None:
787                graph = self._network_view.init_network(graph)
788
789            self.graph = graph
790
791            # if graph has more nodes and edges than pixels in 1600x1200 display,
792            # it is too big to visualize!
793            if self.graph.number_of_nodes() + self.graph.number_of_edges() > 50000:
794                self.set_graph_none()
795                self.error('Graph is too big to visualize. Try using one of the network views.')
796                return
797
798            if self.items_matrix is not None and self.items_matrix.dim != self.graph_base.number_of_nodes():
799                self.set_items_distance_matrix(None)
800
801            self.number_of_nodes_label = self.graph.number_of_nodes()
802            self.number_of_edges_label = self.graph.number_of_edges()
803
804            self.networkCanvas.set_graph(self.graph, curve, items=self.graph_base.items(), links=self.graph_base.links())
805
806            if self._items is not None and 'x' in self._items.domain and 'y' in self._items.domain:
807                positions = dict((node, (self._items[node]['x'].value, self._items[node]['y'].value)) \
808                             for node in self.graph if self._items[node]['x'].value != '?' \
809                             and self._items[node]['y'].value != '?')
810
811                self.networkCanvas.networkCurve.set_node_coordinates(positions)
812
813
814            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
815            self.networkCanvas.maxEdgeSize = self.maxLinkSize
816            self.networkCanvas.minComponentEdgeWidth = self.minComponentEdgeWidth
817            self.networkCanvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
818            self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)
819
820            self.compute_network_info()
821            self._set_combos()
822
823            lastNameComponentAttributeFound = False
824            for i in range(self.nameComponentCombo.count()):
825                if self.lastNameComponentAttribute == self.nameComponentCombo.itemText(i):
826                    lastNameComponentAttributeFound = True
827                    self.nameComponentAttribute = i
828                    self.nameComponents()
829                    self.showComponentAttribute = self.showComponentCombo.count() - 1
830                    self.showComponents()
831                    break
832
833            if not lastNameComponentAttributeFound:
834                self.lastNameComponentAttribute = ''
835
836            self.showComponentAttribute = None
837
838            t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
839            self.frSteps = int(2.0 / t)
840            if self.frSteps < 1: self.frSteps = 1
841            if self.frSteps > 100: self.frSteps = 100
842
843            # if graph is large, set random layout, min vertex size, min edge size
844            if self.frSteps < 10:
845                self.networkCanvas.update_antialiasing(False)
846                self.networkCanvas.update_animations(False)
847                self.minVertexSize = 5
848                self.maxVertexSize = 5
849                self.maxLinkSize = 1
850                self.optMethod = 0
851                self.graph_layout_method()
852
853            self.networkCanvas.labelsOnMarkedOnly = self.labelsOnMarkedOnly
854            self.networkCanvas.showWeights = self.showWeights
855
856            self.set_node_sizes()
857            self.set_node_colors()
858            self.set_edge_sizes()
859            self.set_edge_colors()
860
861            self._clicked_att_lstbox()
862            self._clicked_tooltip_lstbox()
863            self._clicked_edge_label_listbox()
864
865            self.optButton.setChecked(1)
866            self.graph_layout()
867
868        def set_network_view(self, nxView):
869            self.error()
870            self.warning()
871            self.information()
872
873            if self.graph is None:
874                self.information('Do not forget to add a graph!')
875
876            if self._network_view is not None:
877                QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
878
879            self._network_view = nxView
880
881            if self._network_view is not None:
882                self._network_view.set_nx_explorer(self)
883
884            self.set_graph(self.graph_base)
885
886            if self._network_view is not None:
887                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
888
889        def set_items(self, items=None):
890            self.error()
891            self.warning()
892            self.information()
893
894            if items is None:
895                return
896
897            if self.graph is None:
898                self.warning('No graph found!')
899                return
900
901            if len(items) != self.graph_base.number_of_nodes():
902                self.error('Table items must have one example for each node.')
903                return
904
905            self.graph_base.set_items(items)
906
907            self.set_node_sizes()
908            self.networkCanvas.items = items
909            self.networkCanvas.showWeights = self.showWeights
910            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
911            self._set_combos()
912            #self.networkCanvas.updateData()
913
914        def mark_items(self, items):
915            self.markInputCombo.clear()
916            self.markInputRadioButton.setEnabled(False)
917            self.markInputItems = items
918
919            self.error()
920            self.warning()
921            self.information()
922
923            if items is None:
924                return
925
926            if self.graph is None or self.graph_base.items() is None or items is None:
927                self.warning('No graph found or no items attached to the graph.')
928                return
929
930            if len(items) > 0:
931                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()]
932                lstNewDomain = [x.name for x in items.domain] + [items.domain[x].name for x in items.domain.getmetas()]
933                commonVars = set(lstNewDomain) & set(lstOrgDomain)
934
935                self.markInputCombo.addItem(self.icons[Orange.data.Type.Discrete], unicode("ID"))
936
937                if len(commonVars) > 0:
938                    for var in commonVars:
939                        orgVar = self.graph_base.items().domain[var]
940                        mrkVar = items.domain[var]
941
942                        if orgVar.varType == mrkVar.varType and orgVar.varType == Orange.data.Type.String:
943                            self.markInputCombo.addItem(self.icons[orgVar.varType], unicode(orgVar.name))
944
945                self.markInputRadioButton.setEnabled(True)
946                self.set_mark_mode(9)
947
948        def set_explore_distances(self):
949            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
950
951            if self.explore_distances:
952                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
953
954        def explore_focused(self):
955            sel = self.networkCanvas.selected_nodes()
956            if len(sel) == 1:
957                ndx_1 = sel[0]
958                self.networkCanvas.label_distances = [['%.2f' % \
959                                self.items_matrix[ndx_1][ndx_2]] \
960                                for ndx_2 in self.networkCanvas.graph.nodes()]
961            else:
962                self.networkCanvas.label_distances = None
963
964            self.networkCanvas.set_node_labels(self.lastLabelColumns)
965            self.networkCanvas.replot()
966
967        #######################################################################
968        ### Layout Optimization                                             ###
969        #######################################################################
970
971        def graph_layout(self):
972            if self.graph is None or self.graph.number_of_nodes <= 0:   #grafa se ni
973                self.optButton.setChecked(False)
974                return
975
976            if not self.optButton.isChecked() and not self.optMethod in [2, 3, 9, 10]:
977                self.optButton.setChecked(False)
978                return
979
980            qApp.processEvents()
981
982            if self.optMethod == 1:
983                self.networkCanvas.networkCurve.random()
984            elif self.optMethod == 2:
985                self.graph_layout_fr(False)
986            elif self.optMethod == 3:
987                self.graph_layout_fr(True)
988            elif self.optMethod == 4:
989                self.graph_layout_fr_radial()
990            elif self.optMethod == 5:
991                self.networkCanvas.networkCurve.circular(\
992                                            NetworkCurve.circular_crossing)
993            elif self.optMethod == 6:
994                self.networkCanvas.networkCurve.circular(\
995                                            NetworkCurve.circular_original)
996            elif self.optMethod == 7:
997                self.networkCanvas.networkCurve.circular(\
998                                            NetworkCurve.circular_random)
999            elif self.optMethod == 8:
1000                self.graph_layout_fragviz()
1001            elif self.optMethod == 9:
1002                self.graph_layout_mds()
1003            elif self.optMethod == 10:
1004                self.graph_layout_pivot_mds()
1005
1006            self.optButton.setChecked(False)
1007            self.networkCanvas.update_canvas()
1008
1009        def graph_layout_method(self, method=None):
1010            self.information()
1011            self.stepsSpin.label.setText('Iterations: ')
1012            self.optButton.setEnabled(True)
1013            self.cb_opt_from_curr.setEnabled(False)
1014
1015            if method is not None:
1016                self.optMethod = method
1017
1018            if str(self.optMethod) == '0':
1019                self.optButton.setEnabled(False)
1020            else:
1021                self.optButton.setEnabled(True)
1022
1023            if str(self.optMethod) in ['2', '3', '4']:
1024                self.stepsSpin.setEnabled(True)
1025
1026            elif str(self.optMethod) in ['8', '9', '10']:
1027                if str(self.optMethod) == '8':
1028                    self.stepsSpin.label.setText('Pivots: ')
1029
1030                if str(self.optMethod) in ['9', '10']:
1031                    self.cb_opt_from_curr.setEnabled(True)
1032
1033                self.stepsSpin.setEnabled(True)
1034
1035                if self.items_matrix is None:
1036                    self.information('Set distance matrix to input signal')
1037                    self.optButton.setEnabled(False)
1038                    return
1039                if self.graph is None:
1040                    self.information('No network found')
1041                    self.optButton.setEnabled(False)
1042                    return
1043                if self.items_matrix.dim != self.graph.number_of_nodes():
1044                    self.error('Distance matrix dimensionality must equal number of vertices')
1045                    self.optButton.setEnabled(False)
1046                    return
1047            else:
1048                self.stepsSpin.setEnabled(False)
1049                self.optButton.setChecked(True)
1050                self.graph_layout()
1051
1052        def mds_progress(self, avgStress, stepCount):
1053            #self.drawForce()
1054
1055            #self.mdsInfoA.setText("Avg. Stress: %.20f" % avgStress)
1056            #self.mdsInfoB.setText("Num. steps: %i" % stepCount)
1057            self.progressBarSet(int(stepCount * 100 / self.frSteps))
1058            qApp.processEvents()
1059
1060        def graph_layout_fragviz(self):
1061            if self.items_matrix is None:
1062                self.information('Set distance matrix to input signal')
1063                self.optButton.setChecked(False)
1064                return
1065
1066            if self.layout is None:
1067                self.information('No network found')
1068                self.optButton.setChecked(False)
1069                return
1070
1071            if self.items_matrix.dim != self.graph.number_of_nodes():
1072                self.error('Distance matrix dimensionality must equal number of vertices')
1073                self.optButton.setChecked(False)
1074                return
1075
1076            if not self.optButton.isChecked():
1077                self.networkCanvas.networkCurve.stopMDS = True
1078                self.optButton.setChecked(False)
1079                self.optButton.setText("Optimize layout")
1080                return
1081
1082            self.optButton.setText("Stop")
1083            self.progressBarInit()
1084            qApp.processEvents()
1085
1086            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1087                matrix = self.items_matrix
1088            else:
1089                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1090
1091            self.networkCanvas.networkCurve.layout_fragviz(self.frSteps, matrix, self.graph, self.mds_progress, self.opt_from_curr)
1092
1093            self.optButton.setChecked(False)
1094            self.optButton.setText("Optimize layout")
1095            self.progressBarFinished()
1096
1097        def graph_layout_mds(self):
1098            if self.items_matrix is None:
1099                self.information('Set distance matrix to input signal')
1100                self.optButton.setChecked(False)
1101                return
1102
1103            if self.layout is None:
1104                self.information('No network found')
1105                self.optButton.setChecked(False)
1106                return
1107
1108            if self.items_matrix.dim != self.graph.number_of_nodes():
1109                self.error('Distance matrix dimensionality must equal number of vertices')
1110                self.optButton.setChecked(False)
1111                return
1112
1113            if not self.optButton.isChecked():
1114                self.networkCanvas.networkCurve.stopMDS = True
1115                self.optButton.setChecked(False)
1116                self.optButton.setText("Optimize layout")
1117                return
1118
1119            self.optButton.setText("Stop")
1120            self.progressBarInit()
1121            qApp.processEvents()
1122
1123            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1124                matrix = self.items_matrix
1125            else:
1126                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1127
1128            self.networkCanvas.networkCurve.layout_mds(self.frSteps, matrix, self.mds_progress, self.opt_from_curr)
1129
1130            self.optButton.setChecked(False)
1131            self.optButton.setText("Optimize layout")
1132            self.progressBarFinished()
1133
1134        def graph_layout_fr(self, weighted):
1135            if self.graph is None:
1136                return
1137
1138            if not self.optButton.isChecked():
1139                self.networkCanvas.networkCurve.stop_optimization()
1140                self.optButton.setChecked(False)
1141                self.optButton.setText("Optimize layout")
1142                return
1143
1144            self.optButton.setText("Stop")
1145            qApp.processEvents()
1146            self.networkCanvas.networkCurve.layout_fr(self.frSteps, False)
1147            self.networkCanvas.update_canvas()
1148            self.optButton.setChecked(False)
1149            self.optButton.setText("Optimize layout")
1150
1151        def graph_layout_fr_radial(self):
1152            if self.graph is None:   #grafa se ni
1153                return
1154
1155    #        #print "F-R Radial"
1156    #        k = 1.13850193174e-008
1157    #        nodes = self.graph.number_of_nodes()
1158    #        t = k * nodes * nodes
1159    #        refreshRate = int(5.0 / t)
1160    #        if refreshRate <    1: refreshRate = 1
1161    #        if refreshRate > 1500: refreshRate = 1500
1162    #        #print "refreshRate: " + str(refreshRate)
1163    #       
1164    #        tolerance = 5
1165    #        initTemp = 100
1166    #        centerNdx = 0
1167    #       
1168    #        selection = self.networkCanvas.getSelection()
1169    #        if len(selection) > 0:
1170    #            centerNdx = selection[0]
1171    #           
1172    #        #print "center ndx: " + str(centerNdx)
1173    #        initTemp = self.layout.fr_radial(centerNdx, refreshRate, initTemp)
1174    #        self.networkCanvas.circles = [10000 / 12, 10000/12*2, 10000/12*3]#, 10000/12*4, 10000/12*5]
1175    #        #self.networkCanvas.circles = [100, 200, 300]
1176    #        self.networkCanvas.updateCanvas()
1177    #        self.networkCanvas.circles = []
1178
1179        def graph_layout_pivot_mds(self):
1180            self.information()
1181
1182            if self.items_matrix is None:
1183                self.information('Set distance matrix to input signal')
1184                return
1185
1186            if self.graph_base is None:
1187                self.information('No network found')
1188                return
1189
1190            if self.items_matrix.dim != self.graph_base.number_of_nodes():
1191                self.error('The number of vertices does not match matrix size.')
1192                return
1193
1194            self.frSteps = min(self.frSteps, self.graph.number_of_nodes())
1195            qApp.processEvents()
1196
1197            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1198                matrix = self.items_matrix
1199            else:
1200                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1201
1202            mds = orngMDS.PivotMDS(matrix, self.frSteps)
1203            x, y = mds.optimize()
1204            xy = zip(list(x), list(y))
1205            coors = dict(zip(sorted(self.graph.nodes()), xy))
1206            self.networkCanvas.networkCurve.set_node_coordinates(coors)
1207            self.networkCanvas.update_canvas()
1208
1209        #######################################################################
1210        ### Network Visualization                                           ###
1211        #######################################################################
1212
1213        def _set_colors(self):
1214            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
1215            if dlg.exec_():
1216                self.colorSettings = dlg.getColorSchemas()
1217                self.selectedSchemaIndex = dlg.selectedSchemaIndex
1218                self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
1219                self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
1220
1221                self.set_node_colors()
1222
1223        def _set_edge_color_palette(self):
1224            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
1225            if dlg.exec_():
1226                self.edgeColorSettings = dlg.getColorSchemas()
1227                self.selectedEdgeSchemaIndex = dlg.selectedSchemaIndex
1228                self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
1229                self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
1230
1231                self.set_edge_colors()
1232
1233        def _create_color_dialog(self, colorSettings, selectedSchemaIndex):
1234            c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
1235            c.createDiscretePalette("discPalette", "Discrete Palette")
1236            c.createContinuousPalette("contPalette", "Continuous Palette")
1237            c.setColorSchemas(colorSettings, selectedSchemaIndex)
1238            return c
1239
1240        def _clicked_att_lstbox(self):
1241            if self.graph is None:
1242                return
1243
1244            self.lastLabelColumns = [self.attributes[i][0] for i in self.markerAttributes]
1245            self.networkCanvas.set_node_labels(self.lastLabelColumns)
1246            self.networkCanvas.replot()
1247
1248        def _clicked_tooltip_lstbox(self):
1249            if self.graph is None:
1250                return
1251
1252            self.lastTooltipColumns = [self.attributes[i][0] for i in self.tooltipAttributes]
1253            self.networkCanvas.set_tooltip_attributes(self.lastTooltipColumns)
1254            self.networkCanvas.replot()
1255
1256        def _clicked_edge_label_listbox(self):
1257            if self.graph is None:
1258                return
1259
1260            self.lastEdgeLabelAttributes = set([self.edgeAttributes[i][0] for i in self.edgeLabelAttributes])
1261            self.networkCanvas.set_edge_labels(self.lastEdgeLabelAttributes)
1262            self.networkCanvas.replot()
1263
1264        def set_node_colors(self):
1265            if self.graph is None:
1266                return
1267
1268            self.networkCanvas.set_node_colors(self.colorCombo.currentText())
1269            self.lastColorColumn = self.colorCombo.currentText()
1270
1271        def set_edge_colors(self):
1272            if self.graph is None:
1273                return
1274
1275            self.networkCanvas.set_edge_colors(self.edgeColorCombo.currentText())
1276            self.lastEdgeColorColumn = self.edgeColorCombo.currentText()
1277
1278        def set_edge_sizes(self):
1279            if self.graph is None:
1280                return
1281
1282            self.networkCanvas.networkCurve.set_edge_sizes(self.maxLinkSize)
1283            self.networkCanvas.replot()
1284
1285        def set_node_sizes(self):
1286            if self.graph is None or self.networkCanvas is None:
1287                return
1288
1289            if self.minVertexSize > self.maxVertexSize:
1290                self.maxVertexSize = self.minVertexSize
1291
1292            items = self.graph_base.items()
1293
1294            if items is None:
1295                self.networkCanvas.networkCurve.set_node_sizes({}, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1296                return
1297
1298            self.lastVertexSizeColumn = self.vertexSizeCombo.currentText()
1299            column = str(self.vertexSizeCombo.currentText())
1300
1301            values = {}
1302            if column in items.domain or (column.startswith("num of ") and column.replace("num of ", "") in items.domain):
1303                if column in items.domain:
1304                    values = dict((x, items[x][column].value) for x in self.graph if not items[x][column].isSpecial())
1305                else:
1306                    values = dict((x, len(items[x][column.replace("num of ", "")].value.split(','))) for x in self.graph)
1307
1308            if len(values) == 0:
1309                values = dict((node, 1.) for node in self.graph)
1310
1311            if self.invertSize:
1312                maxval = max(values.itervalues())
1313                values.update((key, maxval - val) for key, val in values.iteritems())
1314                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1315            else:
1316                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1317
1318            self.networkCanvas.replot()
1319
1320        def set_font(self):
1321            if self.networkCanvas is None:
1322                return
1323
1324            weights = {0: 50, 1: 80}
1325
1326            font = self.networkCanvas.font()
1327            font.setPointSize(self.fontSize)
1328            font.setWeight(weights[self.fontWeight])
1329            self.networkCanvas.setFont(font)
1330            self.networkCanvas.fontSize = font
1331            self.networkCanvas.set_node_labels()
1332
1333        def sendReport(self):
1334            self.reportSettings("Graph data",
1335                                [("Number of vertices", self.graph.number_of_nodes()),
1336                                 ("Number of edges", self.graph.number_of_edges()),
1337                                 ("Vertices per edge", "%.3f" % self.verticesPerEdge),
1338                                 ("Edges per vertex", "%.3f" % self.edgesPerVertex),
1339                                 ])
1340            if self.color or self.vertexSize or self.markerAttributes or self.edgeColor:
1341                self.reportSettings("Visual settings",
1342                                    [self.color and ("Vertex color", self.colorCombo.currentText()),
1343                                     self.vertexSize and ("Vertex size", str(self.vertexSizeCombo.currentText()) + " (inverted)" if self.invertSize else ""),
1344                                     self.markerAttributes and ("Labels", ", ".join(self.attributes[i][0] for i in self.markerAttributes)),
1345                                     self.edgeColor and ("Edge colors", self.edgeColorCombo.currentText()),
1346                                    ])
1347            self.reportSettings("Optimization",
1348                                [("Method", self.optCombo.currentText()),
1349                                 ("Iterations", self.frSteps)])
1350            self.reportSection("Graph")
1351            self.reportImage(self.networkCanvas.saveToFileDirect)
1352
1353        #######################################################################
1354        ### PROTOTYPE                                                       ###
1355        #######################################################################
1356
1357        def set_component_edge_width(self, changedMin=True):
1358            if self.networkCanvas is None:
1359                return
1360
1361            canvas = self.networkCanvas
1362            if changedMin:
1363                if self.maxComponentEdgeWidth < self.minComponentEdgeWidth:
1364                    self.maxComponentEdgeWidth = self.minComponentEdgeWidth
1365            else:
1366                if self.minComponentEdgeWidth > self.maxComponentEdgeWidth:
1367                    self.minComponentEdgeWidth = self.maxComponentEdgeWidth
1368
1369            canvas.minComponentEdgeWidth = self.minComponentEdgeWidth
1370            canvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
1371            self.networkCanvas.updateCanvas()
1372
1373        def showComponents(self):
1374            if self.graph is None or self.graph_base.items() is None:
1375                return
1376
1377            vars = [x.name for x in self.graph_base.items_vars()]
1378
1379            if not self.showComponentCombo.currentText() in vars:
1380                self.networkCanvas.showComponentAttribute = None
1381                self.lastNameComponentAttribute = ''
1382            else:
1383                self.networkCanvas.showComponentAttribute = self.showComponentCombo.currentText()
1384
1385            self.networkCanvas.drawComponentKeywords()
1386
1387        def nameComponents(self):
1388            """Names connected components of genes according to GO terms."""
1389            self.progressBarFinished()
1390            self.lastNameComponentAttribute = None
1391
1392            if self.graph is None or self.graph_base.items() is None:
1393                return
1394
1395            vars = [x.name for x in self.graph_base.items_vars()]
1396            if not self.nameComponentCombo.currentText() in vars:
1397                return
1398
1399            self.progressBarInit()
1400            components = [c for c in Orange.network.nx.algorithms.components.connected_components(self.graph) if len(c) > 1]
1401            if 'component name' in self.graph_base.items().domain:
1402                keyword_table = self.graph_base.items()
1403            else:
1404                keyword_table = Orange.data.Table(Orange.data.Domain(Orange.data.variable.String('component name')), [[''] for i in range(len(self.graph_base.items()))])
1405
1406            import obiGO
1407            ontology = obiGO.Ontology.Load(progressCallback=self.progressBarSet)
1408            annotations = obiGO.Annotations.Load(self.organism, ontology=ontology, progressCallback=self.progressBarSet)
1409
1410            allGenes = set([e[str(self.nameComponentCombo.currentText())].value for e in self.graph_base.items()])
1411            foundGenesets = False
1412            if len(annotations.geneNames & allGenes) < 1:
1413                allGenes = set(reduce(operator.add, [e[str(self.nameComponentCombo.currentText())].value.split(', ') for e in self.graph_base.items()]))
1414                if len(annotations.geneNames & allGenes) < 1:
1415                    self.warning('no genes found')
1416                    return
1417                else:
1418                    foundGenesets = True
1419
1420            def rank(a, j, reverse=False):
1421                if len(a) <= 0: return
1422
1423                if reverse:
1424                    a.sort(lambda x, y: 1 if x[j] > y[j] else -1 if x[j] < y[j] else 0)
1425                    top_value = a[0][j]
1426                    top_rank = len(a)
1427                    max_rank = float(len(a))
1428                    int_ndx = 0
1429                    for k in range(len(a)):
1430                        if top_value < a[k][j]:
1431                            top_value = a[k][j]
1432                            if k - int_ndx > 1:
1433                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1434                                for l in range(int_ndx, k):
1435                                    a[l][j] = avg_rank
1436
1437                            int_ndx = k
1438
1439                        a[k][j] = top_rank / max_rank
1440                        top_rank -= 1
1441
1442                    k += 1
1443                    if k - int_ndx > 1:
1444                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1445                        for l in range(int_ndx, k):
1446                            a[l][j] = avg_rank
1447
1448                else:
1449                    a.sort(lambda x, y: 1 if x[j] < y[j] else -1 if x[j] > y[j] else 0)
1450                    top_value = a[0][j]
1451                    top_rank = len(a)
1452                    max_rank = float(len(a))
1453                    int_ndx = 0
1454                    for k in range(len(a)):
1455                        if top_value > a[k][j]:
1456                            top_value = a[k][j]
1457                            if k - int_ndx > 1:
1458                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1459                                for l in range(int_ndx, k):
1460                                    a[l][j] = avg_rank
1461
1462                            int_ndx = k
1463
1464                        a[k][j] = top_rank / max_rank
1465                        top_rank -= 1
1466
1467                    k += 1
1468                    if k - int_ndx > 1:
1469                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1470                        for l in range(int_ndx, k):
1471                            a[l][j] = avg_rank
1472
1473            for i in range(len(components)):
1474                component = components[i]
1475                if len(component) <= 1:
1476                    continue
1477
1478                if foundGenesets:
1479                    genes = reduce(operator.add, [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value.split(', ') for v in component])
1480                else:
1481                    genes = [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value for v in component]
1482
1483                res1 = annotations.GetEnrichedTerms(genes, aspect="P")
1484                res2 = annotations.GetEnrichedTerms(genes, aspect="F")
1485                res = res1.items() + res2.items()
1486                #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]
1487                #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]
1488
1489                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]
1490                if len(namingScore) == 0:
1491                    continue
1492
1493                annotated_genes = max([a[0] for a in namingScore])
1494
1495                rank(namingScore, 1, reverse=True)
1496                rank(namingScore, 2, reverse=True)
1497                rank(namingScore, 0)
1498
1499                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]
1500                namingScore.sort(reverse=True)
1501
1502                if len(namingScore) < 1:
1503                    print "warning. no annotations found for group of genes: " + ", ".join(genes)
1504                    continue
1505                elif len(namingScore[0]) < 2:
1506                    print "warning. error computing score for group of genes: " + ", ".join(genes)
1507                    continue
1508
1509                for v in component:
1510                    name = str(namingScore[0][1])
1511                    attrs = "%d/%d, %d, %lf" % (namingScore[0][2], annotated_genes, namingScore[0][3], namingScore[0][4])
1512                    info = ''
1513                    if self.showTextMiningInfo:
1514                        info = "\n" + attrs + "\n" + str(namingScore[0][0])
1515                    keyword_table[v]['component name'] = name + info
1516
1517                self.progressBarSet(i * 100.0 / len(components))
1518
1519            self.lastNameComponentAttribute = self.nameComponentCombo.currentText()
1520            self.set_items(Orange.data.Table([self.graph_base.items(), keyword_table]))
1521            self.progressBarFinished()
1522
1523
1524        def setAutoSendAttributes(self):
1525            print 'TODO setAutoSendAttributes'
1526            #if self.autoSendAttributes:
1527            #    self.networkCanvas.callbackSelectVertex = self.sendAttSelectionList
1528            #else:
1529            #    self.networkCanvas.callbackSelectVertex = None
1530
1531        def sendAttSelectionList(self):
1532            if not self.graph is None:
1533                vars = [x.name for x in self.graph_base.links_vars()]
1534                if not self.comboAttSelection.currentText() in vars:
1535                    return
1536                att = str(self.comboAttSelection.currentText())
1537                vertices = self.networkCanvas.selected_nodes()
1538
1539                if len(vertices) != 1:
1540                    return
1541
1542                attributes = str(self.graph_base.items()[vertices[0]][att]).split(', ')
1543            else:
1544                attributes = None
1545            self.send("Features", attributes)
1546
1547
1548except ImportError as err:
1549    try:
1550        from OWNxCanvas import *
1551    except:
1552        # if Qwt is also not installed throw could not import orangeqt error
1553        raise err
1554
1555    from OWNxExplorerQwt import OWNxExplorerQwt as OWNxExplorer
1556
1557if __name__ == "__main__":
1558    a = QApplication(sys.argv)
1559    ow = OWNxExplorer()
1560    ow.show()
1561
1562    def setNetwork(signal, data, id=None):
1563        if signal == 'Network':
1564            ow.set_graph(data)
1565        #if signal == 'Items':
1566        #    ow.set_items(data)
1567
1568    import OWNxFile
1569    owFile = OWNxFile.OWNxFile()
1570    owFile.send = setNetwork
1571    owFile.show()
1572    owFile.selectNetFile(0)
1573
1574    a.exec_()
1575    ow.saveSettings()
1576    owFile.saveSettings()
Note: See TracBrowser for help on using the repository browser.