.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/mixededge/plot_mixed_edge_graph.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_mixededge_plot_mixed_edge_graph.py: ==================================================== MixedEdgeGraph - Graph with different types of edges ==================================================== A ``MixedEdgeGraph`` is a graph comprised of a tuple, :math:`G = (V, E)`. The difference compared to the other networkx graphs are the edges, E. ``E`` is comprised of a set of mixed edges defined by the user. This allows arbitrary representation of graphs with different types of edges. The ``MixedEdgeGraph`` class represents each type of edge using an internal graph that is one of ``nx.Graph`` or ``nx.DiGraph`` classes. Each internal graph represents one type of edge. Semantically a ``MixedEdgeGraph`` with just one type of edge, is just a normal ``nx.Graph` or ``nx.DiGraph`` and should be converted to its appropriate networkx class. For example, causal graphs typically have two types of edges: - ``->`` directed edges representing causal relations - ``<->`` bidirected edges representing the presence of an unobserved confounder. This would type of mixed-edge graph with two internal graphs: a ``nx.DiGraph`` to represent the directed edges, and a ``nx.Graph`` to represent the bidirected edges. .. GENERATED FROM PYTHON SOURCE LINES 28-34 .. code-block:: Python import matplotlib.pyplot as plt import networkx as nx import pywhy_graphs as pg .. GENERATED FROM PYTHON SOURCE LINES 35-39 Construct a MixedEdgeGraph -------------------------- Here we demonstrate how to construct a mixed edge graph by composing networkx graphs. .. GENERATED FROM PYTHON SOURCE LINES 39-69 .. code-block:: Python directed_G = nx.DiGraph( [ ("X", "Y"), ("Z", "X"), ] ) bidirected_G = nx.Graph( [ ("X", "Y"), ] ) directed_G.add_nodes_from(bidirected_G.nodes) bidirected_G.add_nodes_from(directed_G.nodes) G = pg.networkx.MixedEdgeGraph( graphs=[directed_G, bidirected_G], edge_types=["directed", "bidirected"], name="IV Graph", ) pos = nx.spring_layout(G) # we can then visualize the mixed-edge graph fig, ax = plt.subplots() nx.draw_networkx(G.get_graphs(edge_type="directed"), pos=pos, ax=ax) nx.draw_networkx(G.get_graphs(edge_type="bidirected"), pos=pos, ax=ax) ax.set_title("Instrumental Variable Mixed Edge Causal Graph") fig.tight_layout() plt.show(block=False) .. image-sg:: /auto_examples/mixededge/images/sphx_glr_plot_mixed_edge_graph_001.png :alt: Instrumental Variable Mixed Edge Causal Graph :srcset: /auto_examples/mixededge/images/sphx_glr_plot_mixed_edge_graph_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 70-72 Mixed Edge Graph Properties --------------------------- .. GENERATED FROM PYTHON SOURCE LINES 72-91 .. code-block:: Python print(G.name) # G is directed since there are directed edges print(f"{G} is directed: {G.is_directed()} because there are directed edges.") # MixedEdgeGraphs are not multigraphs print(G.is_multigraph()) # the different edge types present in the graph print(G.edge_types) # the internal networkx graphs representing each edge type print(G.get_graphs()) # we can specifically get the networkx graph representation # of any edge, e.g. the bidirected edges bidirected_edges = G.get_graphs("bidirected") .. rst-class:: sphx-glr-script-out .. code-block:: none IV Graph MixedEdgeGraph named 'IV Graph' with 3 nodes and 3 edges and 2 edge types is directed: False because there are directed edges. False ['directed', 'bidirected'] {'directed': , 'bidirected': } .. GENERATED FROM PYTHON SOURCE LINES 92-94 Mixed Edge Graph Operations on Nodes ------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 94-112 .. code-block:: Python # Nodes: Similar to ``nx.Graph`` and ``nx.DiGraph``, the nodes of the graph # can be queried via the same API. By default nodes are stored # inside every internal graph. nodes = G.nodes assert G.order() == len(G) assert len(G) == G.number_of_nodes() print(f"{G} has nodes: {nodes}") # If we add a node, then we can query if the new node is there print(f"Graph has node A: {G.has_node('A')}") G.add_node("A") print(f"Now graph has node A: {G.has_node('A')}") # Now, we can remove the node G.remove_node("A") print(f"Graph has node A: {G.has_node('A')}") .. rst-class:: sphx-glr-script-out .. code-block:: none MixedEdgeGraph named 'IV Graph' with 3 nodes and 3 edges and 2 edge types has nodes: ['X', 'Y', 'Z'] Graph has node A: False Now graph has node A: True Graph has node A: False .. GENERATED FROM PYTHON SOURCE LINES 113-119 Mixed Edge Graph Operations on Edges ------------------------------------ Mixed edge graphs are just like normal networkx graph classes, except that they store an internal networkx graph per edge type. As a result, each edge now corresponds to an 'edge_type', which typically must be specified in edge operations for mixed edge graphs. .. GENERATED FROM PYTHON SOURCE LINES 119-138 .. code-block:: Python # Edges: We can query specific edges by type print(f"The graph has directed edges: {G.edges()['directed']}") # Note these edges correspond to the edges of the internal networkx # DiGraph that represents the directed edges print(G.get_graphs("directed").edges()) # When querying, adding, or removing an edge, you must specify # the edge type as well. # Here, we can add a new Z <-> Y bidirected edge. assert G.has_edge("X", "Y", edge_type="directed") G.add_edge("Z", "Y", edge_type="bidirected") assert not G.has_edge("Z", "Y", edge_type="directed") # Now, we can remove the Z <-> Y bidirected edge. G.remove_edge("Z", "Y", edge_type="bidirected") assert not G.has_edge("Z", "Y", edge_type="bidirected") .. rst-class:: sphx-glr-script-out .. code-block:: none The graph has directed edges: [('X', 'Y'), ('Z', 'X')] [('X', 'Y'), ('Z', 'X')] .. GENERATED FROM PYTHON SOURCE LINES 139-144 Mixed Edge Graph Key Differences -------------------------------- Mixed edge graphs implement the standard networkx API, but the ``adj``, ``edges``, and ``degree`` are functions instead of class properties. Moreover, one can specify the edge type. .. GENERATED FROM PYTHON SOURCE LINES 144-170 .. code-block:: Python # Neighbors: Compared to its uni-edge networkx counterparts, a mixed-edge # graph has many edge types. We define neighbors as any node with a connection. # This is similar to `nx.Graph` where neighbors are any adjacent neighbors. assert "Z" in G.neighbors("X") # Similar to the networkx API, the ``adj`` provides a way to iterate # through the nodes and edges, but now over different edge types. for edge_type, adj in G.adj.items(): print(edge_type) print(adj) # If you only want the adjacencies of the directed edges, you can # query the returned dictionary of adjacencies. print(G.adj["directed"]) # Similar to the networkx API, the ``edges`` provides a way to iterate # through the edges, but now over different edge types. for edge_type, edges in G.edges().items(): print(edge_type) print(edges) # Similar to the networkx API, the ``edges`` provides a way to iterate # through the edges, but now over different edge types. for node, degrees in G.degree().items(): print(f"{node} with degree: {degrees}") .. rst-class:: sphx-glr-script-out .. code-block:: none directed {'X': {'Y': {}}, 'Y': {}, 'Z': {'X': {}}} bidirected {'X': {'Y': {}}, 'Y': {'X': {}}, 'Z': {}} {'X': {'Y': {}}, 'Y': {}, 'Z': {'X': {}}} directed [('X', 'Y'), ('Z', 'X')] bidirected [('X', 'Y')] directed with degree: [('X', 2), ('Y', 1), ('Z', 1)] bidirected with degree: [('X', 1), ('Y', 1), ('Z', 0)] .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.342 seconds) **Estimated memory usage:** 172 MB .. _sphx_glr_download_auto_examples_mixededge_plot_mixed_edge_graph.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_mixed_edge_graph.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_mixed_edge_graph.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_mixed_edge_graph.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_