source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10719:0b86e2af93e0

Revision 10719:0b86e2af93e0, 74.0 KB checked in by mstajdohar, 2 years ago (diff)

Fixed some bugs.

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