pythongraphmatplotlibnetworkx

Interaction between networkx and matplotlib


I am trying networkx and visualization in matplotlib an I'm confused becouse I do not clearly understand how do they interact with each other? There simple example

import matplotlib.pyplot
import networkx as nx
G=nx.path_graph(8)
nx.draw(G)
matplotlib.pyplot.show()

Where do I tell pyplot, that I want to draw graph G? I guess that nx.draw use something like matplotlib.pyplot.{plot, etc ...} So, if I want to draw 2 graphs:

import matplotlib.pyplot
import networkx as nx

G=nx.path_graph(8)
E=nx.path_graph(30)
nx.draw(G)

matplotlib.pyplot.figure()
nx.draw(E)
matplotlib.pyplot.show()

Then... little experiment

import networkx as nx
G=nx.path_graph(8)
E=nx.path_graph(30)
nx.draw(G)
import matplotlib.pyplot
matplotlib.pyplot.figure()
nx.draw(E)
import matplotlib.pyplot as plt
plt.show()

Please don't kill me about this stupid code, I am just trying to understand - how do networkx draw something matplotlib, while it even doesn't import yet!

P.S: Sorry for my English.


Solution

  • Just create two different axes if you want to draw the graphs separately or create a single Axes object an pass it to nx.draw. For example:

    G = nx.path_graph(8)
    E = nx.path_graph(30)
    
    # one plot, both graphs
    fig, ax = subplots()
    nx.draw(G, ax=ax)
    nx.draw(E, ax=ax)
    

    to get:

    enter image description here

    If you want two different figure objects then create them separately, like so:

    G = nx.path_graph(8)
    E = nx.path_graph(30)
    
    # two separate graphs
    fig1 = figure()
    ax1 = fig1.add_subplot(111)
    nx.draw(G, ax=ax1)
    
    fig2 = figure()
    ax2 = fig2.add_subplot(111)
    nx.draw(G, ax=ax2)
    

    yielding:

    enter image description here enter image description here

    Finally, you could create a subplot if you wanted, like this:

    G = nx.path_graph(8)
    E = nx.path_graph(30)
    
    pos=nx.spring_layout(E,iterations=100)
    
    subplot(121)
    nx.draw(E, pos)
    
    subplot(122)
    nx.draw(G, pos)
    

    resulting in:

    enter image description here

    For whatever it's worth it looks like the ax argument to nx.draw is useless with matplotlib's API when you want to create subplots outside of pylab, because nx.draw has some calls to gca which makes it dependent on the pylab interface. Didn't really dig into why that is, just thought I would point it out.

    The source code to nx.draw is fairly straightforward:

    try:
        import matplotlib.pylab as pylab
    except ImportError:
        raise ImportError("Matplotlib required for draw()")
    except RuntimeError:
        print("Matplotlib unable to open display")
        raise
    
    cf=pylab.gcf()
    cf.set_facecolor('w')
    if ax is None:
        if cf._axstack() is None:
            ax=cf.add_axes((0,0,1,1))
        else:
            ax=cf.gca()
    
    # allow callers to override the hold state by passing hold=True|False
    
    b = pylab.ishold()
    h = kwds.pop('hold', None)
    if h is not None:
        pylab.hold(h)
    try:
        draw_networkx(G,pos=pos,ax=ax,**kwds)
        ax.set_axis_off()
        pylab.draw_if_interactive()
    except:
        pylab.hold(b)
        raise
    pylab.hold(b)
    return
    
    1. A figure is captured from the environment using gcf.
    2. Then an Axes object is added to the figure if one doesn't exist, otherwise get it from the environment using gca.
    3. Make the plot face color white
    4. turn hold on
    5. draw it with an internal function
    6. turn off the axes
    7. lastly if we're in interactive mode, draw it and reraise any exceptions that were caught