source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10466:b52f4c49e735

Revision 10466:b52f4c49e735, 73.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 2 years ago (diff)

Added unicode filename support for the rest of save/load widget dialogs.

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