schrodinger.ui.qt.network_visualizer module¶
network_visualizer.py
Description: This package is meant to help with the visualization of network- connection data, in conjunction with network_views.py. A good example of the type of data this is meant to visualize is at: http://networkx.lanl.gov/index.html
The Graph
class is meant as a wrapper for networkx.Graph
objects, which can
then act as a model for AbstractNetworkView
and the associated network view
classes defined in network_views.py.
Copyright Schrodinger, LLC. All rights reserved.
- class schrodinger.ui.qt.network_visualizer.SyncLevels(value)¶
Bases:
enum.IntEnum
Network view manages synchronization between the graph and the view. When the graph changes, the view is updated to ensure the node, edges and the selection state are the same.
When synchronizing multiple views with the graph, if a view triggers another graph synchronization then the views can reach an inconsistent state because not all views were updated the first time. To prevent this, we use synchronization levels to catch nested illegal synchronization attempts. Synchronization actions are assigned a level with the constraint that when sync level N is in progress then only sync level N+1 or higher actions can be triggered.
Synchronization actions:
* Nodes (add, delete, change) * Edges (add, delete)
Network view also has superset methods for synchronizing the entire graph.
- RECURSIVE = 0¶
- ALL = 1¶
- MODEL = 2¶
- NODES = 3¶
- NODES_ADDED = 4¶
- NODES_DELETED = 4¶
- NODES_CHANGED = 4¶
- EDGES = 5¶
- EDGES_ADDED = 6¶
- EDGES_DELETED = 6¶
- class schrodinger.ui.qt.network_visualizer.GraphSignals(*args, **kwargs)¶
Bases:
PyQt6.QtCore.QObject
- selectionChanged¶
- positionChanged¶
- nodesChanged¶
- nodesAdded¶
- nodesDeleted¶
- edgesChanged¶
- graphChanged¶
- undoPointSet¶
- __init__(*args, **kwargs)¶
- blockSignals(self, b: bool) bool ¶
- childEvent(self, a0: QChildEvent)¶
- children(self) List[QObject] ¶
- connectNotify(self, signal: QMetaMethod)¶
- customEvent(self, a0: QEvent)¶
- deleteLater(self)¶
- destroyed¶
destroyed(self, object: typing.Optional[QObject] = None) [signal]
- disconnect(a0: QMetaObject.Connection) bool ¶
- disconnect(self) None
- disconnectNotify(self, signal: QMetaMethod)¶
- dumpObjectInfo(self)¶
- dumpObjectTree(self)¶
- dynamicPropertyNames(self) List[QByteArray] ¶
- event(self, a0: QEvent) bool ¶
- eventFilter(self, a0: QObject, a1: QEvent) bool ¶
- findChild(self, type: type, name: str = '', options: Qt.FindChildOption = Qt.FindChildrenRecursively) QObject ¶
- findChild(self, types: Tuple, name: str = '', options: Qt.FindChildOption = Qt.FindChildrenRecursively) QObject
- findChildren(self, type: type, name: str = '', options: Qt.FindChildOption = Qt.FindChildrenRecursively) List[QObject] ¶
- findChildren(self, types: Tuple, name: str = '', options: Qt.FindChildOption = Qt.FindChildrenRecursively) List[QObject]
- findChildren(self, type: type, re: QRegularExpression, options: Qt.FindChildOption = Qt.FindChildrenRecursively) List[QObject]
- findChildren(self, types: Tuple, re: QRegularExpression, options: Qt.FindChildOption = Qt.FindChildrenRecursively) List[QObject]
- inherits(self, classname: str) bool ¶
- installEventFilter(self, a0: QObject)¶
- isSignalConnected(self, signal: QMetaMethod) bool ¶
- isWidgetType(self) bool ¶
- isWindowType(self) bool ¶
- killTimer(self, id: int)¶
- metaObject(self) QMetaObject ¶
- moveToThread(self, thread: QThread)¶
- objectName(self) str ¶
- objectNameChanged¶
objectNameChanged(self, objectName: str) [signal]
- parent(self) QObject ¶
- property(self, name: str) Any ¶
- pyqtConfigure(...)¶
Each keyword argument is either the name of a Qt property or a Qt signal. For properties the property is set to the given value which should be of an appropriate type. For signals the signal is connected to the given value which should be a callable.
- receivers(self, signal: PYQT_SIGNAL) int ¶
- removeEventFilter(self, a0: QObject)¶
- sender(self) QObject ¶
- senderSignalIndex(self) int ¶
- setObjectName(self, name: str)¶
- setParent(self, a0: QObject)¶
- setProperty(self, name: str, value: Any) bool ¶
- signalsBlocked(self) bool ¶
- startTimer(self, interval: int, timerType: Qt.TimerType = Qt.CoarseTimer) int ¶
- staticMetaObject = <PyQt6.QtCore.QMetaObject object>¶
- thread(self) QThread ¶
- timerEvent(self, a0: QTimerEvent)¶
- tr(sourceText: str, disambiguation: typing.Optional[str] = None, n: int = - 1) str ¶
- schrodinger.ui.qt.network_visualizer.restrict_nested_syncing(func, level: Union[int, schrodinger.ui.qt.network_visualizer.SyncLevels] = 0, *args, **kwargs)¶
A decorator for restricting illegal nested syncing. Level should be greater than the current sync level.
- class schrodinger.ui.qt.network_visualizer.Graph(ggraph=None, node_class=None, edge_class=None)¶
Bases:
object
A model class for an undirected graph. This wraps around the NetworkX Graph class and provides QT signals, a easier-to-use API, and access control.
All persistent data should be stored in self._ggraph.
Note that Graph itself cannot be pickled; Graph has Graph.signals, which is a QObject and cannot be pickled. For this reason selection information (which contains references to Graph) is not placed in self._ggraph, so that self._ggraph can be pickled.
- __init__(ggraph=None, node_class=None, edge_class=None)¶
Constructs a new Graph object
- property ggraph¶
- update()¶
Update any derived aspects of the graph after changes.
- setEdgeValidator(validator)¶
Set an edge validator that will be run when adding edges between nodes. :param validator: the validator :type validator: ConnectionValidator
- toNetworkX()¶
Return a copy of the underlying NetworkX graph.
- getData(key)¶
Return the requested item from the graph’s data dictionary. Returns None if the key is not found.
- setData(key, value, signal=True)¶
Set the value of an item in the graph’s data dictionary.
- isConnected()¶
Checks whether the graph is connected, that is, whether every node is connected by some path to every other node.
- Returns
Whether the graph is connected rtype: bool
- nodeCount()¶
- Returns
the number of nodes in the graph
- Return type
int
- getIsolates()¶
- Returns
a complete set of nodes in the graph that have degree 0
- Return type
set(Node)
- getConnectedComponents(nodes=None)¶
Return a set of nodes for each connected component in the graph.
- Parameters
nodes (set(Node) or NoneType) – optionally, a set of nodes to filter the returned components. If provided, this method will only return components for which at least one node is in
nodes
- Returns
a generater over each connected component in the graph
- Return type
typing.Generator[set[Node], None, None]
- getNodeConnectedComponent(node)¶
Return a set of nodes that are part of the same connected component as
node
.
- getNode(node_key)¶
Retrieve a node via its name. Retrieved nodes are cached, so getting the same Node again will return the same instance. Returns None if no matching Node exists.
- Parameters
node_key (object) – a node, gnode, or string that corresponds to the desired node
- Returns
a node if found, else
None
- Return type
Node or NoneType
- getNodes(node_keys=None)¶
Retrieve a set of nodes optionally indicated by a list of keys. If none is provided, return all nodes.
- Parameters
node_keys (list(object) or NoneType) – optionally, a list of nodes, gnodes, or strings that correspond to the desired nodes
- Returns
a set of nodes
- Return type
set(Node)
- getNeighbors(node)¶
Return a set of all nodes connected to a specified node
- Parameters
node (Node) – center node
- Returns
neighboring nodes
- Return type
set of Node
- addNodes(nodes, signal=True)¶
Add a list of nodes to this graph. The
nodes
argument can either be a list ofNode
objects or a list of hashable objects that can be used as new gnodes.Note that any time a new gnode is created for use in this graph, its string representation must be unique among the other nodes in this graph: nodes are keyed in the
node_objects
dictionary by the string representation of their corresponding gnode.
- addNode(node, signal=True)¶
Convenience method for adding a single node to the graph. See
addNodes()
for full documentation.
- removeNodes(nodes, signal=True)¶
Remove specified nodes from the graph and optionally emit a signal.
- Parameters
nodes (list(Node)) – a list of nodes to be removed
signal (bool) – whether to emit a
nodesDeleted
signal when done
- removeNode(node, signal=True)¶
Convenience function for removing a single node. See
removeNode()
for full documentation.- Parameters
node (
object
orNode
) – a gnode or node to removesignal (bool) – whether to emit a
nodesDeleted
signal when done
- setMultipleNodePos(pos_dict, signal=True)¶
Set the positions of nodes from a dictionary.
- Parameters
pos_dict (dict {Node : (int, int)}) – A dictionary mapping nodes to (x,y) tuples.
- edgeCount()¶
- Returns
the number of edges in the graph
- Return type
int
- hasEdge(node1, node2)¶
Return whether there is an edge between the supplied nodes.
- getGEdge(node0, node1)¶
Return the underlying gedge object corresponding to two supplied nodes. This can be overwritten in subclasses, but the returned class should define a consistent edge ordering that is independent of the order of the supplied node parameters.
- getEdge(node0, node1)¶
Given two nodes, return the corresponding edge if it exists.
- getEdges(nodes=None)¶
Return all edges connected to a node or set of nodes. If no node is specified, all the edges in the graph are returned.
- addEdges(edge_tuples, signal=True)¶
Add edges to graph.
- addEdge(node1, node2, signal=True, data=None)¶
Convenience function to add a single edge to the graph given two nodes. The order of the nodes does not matter.
- removeEdges(edges, signal=True)¶
Removes specified edges from the graph.
- Parameters
edges (list(Edge)) – a list of edges
signal (bool) – whether
edgesChanged
signal should be emitted when done
- removeEdge(edge, signal=True)¶
Convenience function to remove a single edge from the graph.
- Parameters
edge (Edge) – an edge
signal (bool) – whether
edgesChanged
signal should be emitted when done
- getEdgeApproval(node1, node2)¶
Test whether a new edge can be added between two nodes. Doesn’t actually add an edge, just returns whether it is allowable to add.
- selectedNodes()¶
Return the currently selected nodes.
- Return type
set of Nodes
- setSelectedObjs(objs, source=None, signal=True)¶
Specify the current selection.
- springLayout(signal=True)¶
Performs a spring layout on the current graph.
- minCrossingSpringLayout(num_iterations=100, fixed_nodes=None, fraction=1.0)¶
Perform multiple spring layouts and keep the one with the fewest edge intersections, keeping the original positions if the layout could not be improved.
- Parameters
num_iterations (int) – number of spring layouts to try
fixed (iterable of Node) – nodes for which the position should be fixed
signal (bool) – whether to emit the positionChanged signal
fraction (float) – stop iterating if no reduction in crossings is found within this fraction of num_iterations
- hasPositions(accept_partial=False)¶
Determines whether the nodes in this graph have x-y coordinates.
- Parameters
accept_partial (bool) – if set to True, the method will check whether at least one node has coordinates. Otherwise it requires that all nodes have coordinates.
- getState()¶
Get the current state of the Graph
- setState(state)¶
Set the current state of the Graph
- setUndoPoint(signal=True)¶
Store the current state to the undo stack. Also wipes out the redo stack.
- undo()¶
Revert to the last state on the undo stack.
- redo()¶
Undo the undo
- clearUndoHistory()¶
Clears both undo and redo stacks
- merge(g)¶
Merge data from another graph into this graph. Nodes with duplicate names will be considered to be the same ligand.
- Parameters
g (
Graph
) – graph from which data is being merged.
- deleteSelectedItems(include_edges=True, include_nodes=True)¶
Delete selected nodes and/or selected edges.
- Parameters
include_edges (bool) – whether selected edges should be deleted
include_nodes (bool) – whether selected nodes should be deleted
- class schrodinger.ui.qt.network_visualizer.Node(name, graph=None)¶
Bases:
object
Model class for Node. Wraps the NetworkX Graph.node dictionary.
- x_key = 'storedX'¶
- y_key = 'storedY'¶
- __init__(name, graph=None)¶
Construct a Node object. Most of the time, this will be constructed around an existing NetworkX node (i.e. an entry in the networkx.Graph.node dict). If a graph is specified, a node of the same name must exist in the graph, or a ValueError will result.
QT signals will only be emitted if a graph is specified.
- Parameters
name (hashable) – a unique identifier for this node
graph (
Graph
) – the graph object to which this node belongs
- Variables
_gnode – the underlying graph node that this node wraps. In this class, we use the node name as the graph node, but any hashable object can be used.
_gdata – dictionary that stores data belonging to the underlying graph node.
- property gnode¶
Return the underlying graph node object wrapped by this
Node
instance (not the data dictionary_gdata
).
- property name¶
Return unique string associated with this node. Convert to string for subclasses which do not necessarily use strings as graph nodes.
- x()¶
- y()¶
- pos()¶
Returns the Node’s current position coordinates. Returns None if there are no coordinates.
- Return type
tuple (float, float)
- setX(x, signal=True)¶
- setY(y, signal=True)¶
- setPos(x, y, signal=True)¶
Set the node’s position coordinates
- Parameters
x (float) – x coordinate
y (float) – y coordinate
- gdata()¶
Directly access the node data dictionary. Use this object carefully, as directly altering its contents can lead to internal inconsistencies.
This may be wrapped to restrict access.
- getData(key)¶
Return the requested item from the node’s data dictionary. Returns None if the key is not found.
- setData(key, value, signal=True)¶
Set the value of an item in the node’s data dictionary.
- property degree¶
- Returns
the degree (number of edges) of the node
- Return type
int
- class schrodinger.ui.qt.network_visualizer.Edge(gedge, graph)¶
Bases:
object
- __init__(gedge, graph)¶
- Parameters
gedge (object) – the underlying edge object wrapped by this object
graph (Graph) – the graph object to which this edge belongs
- property gedge¶
- Returns
the underlying edge object wrapped by this object
- Return type
fep.graph.Edge
- property nodes¶
- data()¶
- Returns
the data dictionary associated with this edge
- Return type
dict(str, object)
- getData(key)¶
Return the requested item from the edge’s data dictionary. Returns None if the key is not found.
- Parameters
key (str) – the data item key
- Returns
the value stored under the specified key in the edge’s data dictionary, or
None
if it is not found- Return type
object
- setData(key, value, signal=True)¶
Set the specified item in the edge’s data dictionary.
- Parameters
key (str) – the data item key
value (object) – the value to set for the data item
- property name¶
- Returns
the name of the edge, a composite of the connected node names
- Return type
str
- class schrodinger.ui.qt.network_visualizer.ConnectionValidator¶
Bases:
object
Create a subclass of this and assign it using NetworkViewer.setConnectionValidator( ) to do extra work making sure node’s are compatible to connect. val1 and val2 are node1.val and node2.val
- __init__()¶
- validate(node1, node2)¶
- firstNode()¶
- setFirstNode(node)¶
- validateSecondVal(val)¶
- class schrodinger.ui.qt.network_visualizer.AbstractNetworkView¶
Bases:
object
A base class for views on Graph models. Use setModel to replace the model object. Signals from the model are automatically connected to appropriate synchronization slots.
The abstract view does not provide any built-in support for effecting changes back into the model (ex. deleting nodes, changing selection). Any such operations should be implemented in the subclass by making calls directly to the model. These changes will then be automatically synchronized forward to all views.
self.nodes is a dictionary mapping model node objects to view node objects.
self.edges is a dictionary mapping pairs of model node objects to view edge objects. There is no such thing as a edge model object.
Note that all references to the word node and edge in method names refer to view objects. For example, makeNode() will make a view node, addEdge() will add an edge view object to the view.
- Variables
- MODEL_CLASS¶
- __init__()¶
- syncAll()¶
Synchronize the full model and selection state.
- syncRecursive()¶
Synchronize the full model and selection state on this view and all subviews.
- setModelSyncEnabled(enable)¶
Enable or disable automatic synchronization with the model for this view and all subviews.
- setModel(model)¶
Set the model for this view and synchronize to it. Any subviews will have the model set on them as well.
- Parameters
model (Graph) – the graph model
- getSignalsAndSlots(model)¶
Get a list of signal/slot pairs for a model. This list will be used when setting a new model to disconnect the old model signals from their slots and connect the new model’s signals to those slots.
Override this method to modify or extend signals/slots in derived classes.
- Parameters
model (Graph) – the graph model
- addSubview(subview)¶
Add a subview to this view. A subview is another AbstractNetworkView that should always have the same model as its parent view (this view).
Adding will automatically set its model to the current model. Changing the model on this view will result in all its subviews getting the new model set
- Parameters
subview (AbstractNetworkView) – the new subview to add to this view
- removeSubview(subview)¶
Removes the specified subview. The subview is not deleted or altered, and the model remains set.
- Parameters
subview –
- syncModel()¶
- syncNodes()¶
- syncNodesDeleted(nodes)¶
- syncNodesAdded(nodes)¶
- syncNodesChanged(nodes)¶
- syncEdges()¶
- syncSelection(selection, source)¶
- makeNodes(nodes)¶
Create new view nodes and return a dictionary mapping supplied model nodes to corresponding view nodes. Do not add new view nodes to the view.
By default this method returns an “identity dictionary” that maps nodes to themselves. Subclasses should override this method to implement their own view nodes.
- makeNode(node)¶
Convenience method for calling
makeNodes()
with a single node. Rather than returning a dictionary mapping nodes to view nodes, returns the view node corresponding to the supplied node.- Parameters
node (Node) – the model node
- Returns
the view node
- Return type
object
- addNode(viewnode)¶
A convenience function for calling
addNodes()
for a single node.- Parameters
viewnode (object) – a view node
- removeNode(viewnode)¶
Convenience method for calling
removeNode()
for a single node.- Parameters
viewnode (object) – a view node
- updateNode(node)¶
Convenience method for calling
updateNodes()
for a single node.- Parameters
node (Node) – the model node to update to
- getModelNodes(node_keys=None)¶
Retrieve a set of model nodes optionally indicated by a list of keys. If none is provided, return all nodes.
- Parameters
node_keys (list(object) or NoneType) – optionally, a list of nodes, gnodes, or strings that correspond to the desired model nodes
- Returns
a set of nodes
- Return type
set(Node)
- getNode(node)¶
- Parameters
node (Node) – a model node
- Returns
corresponding view node, if available
- Return type
object
orNone
- makeEdges(edges)¶
Given a list of model edges, return a dictionary mapping them to corresponding view edges. Does not add view edges to the view.
By default this method returns an identity dictionary, mapping model edges to themselves. Subclasses should override this method if they want to implement their own view edges.
- Parameters
edges – a list model nodes
- Returns
a dictionary mapping model edges to view edges
- Return type
dict(Edge, object)
- makeEdge(edge)¶
Convenience method for calling
makeEdges()
for a single edge. Rather than return a dictionary mapping model edges to view edges, returns a singe view edge. Does not add a view edge to the view.- Parameters
edge (Edge) – a model edge
- Returns
a view edge
- Return type
object
- addEdge(viewedge)¶
Convenience method for calling
addEdges()
for a single edge.- Parameters
viewedge (object) – the view edge to add to the view
- removeEdge(viewedge)¶
Convenience method for calling
removeEdges()
for a single edge.- Parameters
viewedge (object) – the view edge to remove from the view
- updateEdge(edge)¶
A convenience method for calling
updateEdges()
for a single edge.- Parameters
edge (Edge) – the model edge corresponding to the view edge to update
- getModelEdges(nodes=None)¶
Return all model edges connected to a model node or set of model nodes. If no node is specified, all the edges in the graph are returned. This method acts like
Graph.getEdges()
, but it filters for model edges that are available in this view.
- getEdge(edge)¶
Return the view edge corresponding to the supplied model edge.
- Parameters
edge (Edge) – a model edge
- Returns
the corresponding view edge if available
- Return type
object or None
- getEdges(nodes=None)¶
Return a list of view edges, filtering the list so that the edges are connected to the optionally-supplied node or iterable of nodes.
- Parameters
nodes (iterable[Node] or Node or NoneType) – a node or iterable of nodes
- Returns
list of view edges
- Return type
list[NetworkEdge or NoneType]
- addNodes(viewnodes)¶
Takes view nodes and adds them to the view if that makes sense (eg. add graphics items to scene, add rows to table, etc.) It should not add the view node to
self.nodes
; that is handled in_addNodes()
.- Parameters
viewnodes (list(object)) – view nodes to add to the view
- removeNodes(viewnodes)¶
Removes view nodes from the view if that makes sense (eg. remove graphics items from scene, remove table rows, etc.) It should not remove view nodes from
self.nodes
; that is handled in_removeNodes()
.- Parameters
viewnodes (list(object)) – a list of view nodes
- updateNodes(nodes)¶
Performs any operations necessary to update the view to the current model state. Note that this method takes model nodes, not view nodes.
- Parameters
nodes (list(Node)) – model nodes which must have their views updated
- addEdges(viewedges)¶
Adds view edges to the view. Does not add view edges to
self.edges
.- Parameters
viewedges (list(object)) – view edges to add to the view
- removeEdges(viewedges)¶
Removes view edges from the view. Does not remove view edges from
self.edges
.- Parameters
viewedges (list(object)) – view edges to remove from the view
- updateEdges(edges)¶
Performs any operations necessary to update the view to the current model state.
- Parameters
edges (list(Edge)) – a list of model edges corresponding to view edges that should be updated
- selectItems(selected_view_objects)¶
Selects view objects in the view. Currently only view nodes will be requested, but may be expanded to allow a combination of nodes and edges to be selected.
- Parameters
selected_view_objects (list(object)) – a list of view objects to be selected
- schrodinger.ui.qt.network_visualizer.perp(a)¶
- schrodinger.ui.qt.network_visualizer.seg_intersect(a1, a2, b1, b2)¶
Checks whether two line segments cross each other.
- Parameters
a1 (numpy.array) – first endpoint of line segment a
a2 (numpy.array) – second endpoint of line segment a
b1 (numpy.array) – first endpoint of line segment b
b2 (numpy.array) – second endpoint of line segment b
- Returns
whether the line segments intersect
- Return type
bool
- schrodinger.ui.qt.network_visualizer.fruchterman_reingold_layout(G, dim=2, pos=None, fixed=None, iterations=50, weight='weight', scale=1)¶
Position nodes using Fruchterman-Reingold force-directed algorithm.
- Parameters
G – NetworkX graph
dim (int) – Dimension of layout
pos (dict) – Initial positions for nodes as a dictionary with node as keys and values as a list or tuple. If None, then use random initial positions.
fixed (list) – Nodes to keep fixed at initial position. optional
iterations (int) – Number of iterations of spring-force relaxation
weight (str or None) – The edge attribute that holds the numerical value used for the edge weight. If None, then all edge weights are 1.
scale (float) – Scale factor for positions
- Return type
dict
- Returns
A dictionary of positions keyed by gnode
Examples:
>>> G=nx.path_graph(4) >>> pos=nx.spring_layout(G) # The same using longer function name >>> pos=nx.fruchterman_reingold_layout(G)
- schrodinger.ui.qt.network_visualizer.spring_layout(G, dim=2, pos=None, fixed=None, iterations=50, weight='weight', scale=1)¶
Position nodes using Fruchterman-Reingold force-directed algorithm.
- Parameters
G – NetworkX graph
dim (int) – Dimension of layout
pos (dict) – Initial positions for nodes as a dictionary with node as keys and values as a list or tuple. If None, then use random initial positions.
fixed (list) – Nodes to keep fixed at initial position. optional
iterations (int) – Number of iterations of spring-force relaxation
weight (str or None) – The edge attribute that holds the numerical value used for the edge weight. If None, then all edge weights are 1.
scale (float) – Scale factor for positions
- Return type
dict
- Returns
A dictionary of positions keyed by gnode
Examples:
>>> G=nx.path_graph(4) >>> pos=nx.spring_layout(G) # The same using longer function name >>> pos=nx.fruchterman_reingold_layout(G)