4
votes

I'm using networkx to draw a graph of a network with nodes at given positions on a field. The field is divided into a set amount of cells and the node positions correspond to a cell. When drawing the graph, I would like to show a grid in the background so the cells and distances in the graph are visible. Does networkx offer an option for that? I could not find one. I tried setting the grid via pyplot:

plt.xlim(0,14)
plt.ylim(0,10)
plt.xticks([x for x in xrange(0,14)])
plt.yticks([x for x in xrange(0,10)])
plt.grid(True)

which works by itself (see here) but when also calling

nx.draw(G, pos)

it shows the graph without the grid (see here). I'm guessing the grid is still in the background but networkx draws completely over it.

So is there any way to show the grid with plt or maybe a networkx command that I didn't find which allows something similar?

edit: Here is the complete code used. See the difference when (un)commenting nx.draw(G,pos)

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx


def quit_figure(event):
    if event.key == 'q':
        plt.close(event.canvas.figure)

nodes = [[1,1],[3,1],[6,1],[3,2],[13,1],[3,5]]
distance_array = [
    [[],[],[1,3],[],[5],[],[],[],[],[],[],[],[],[],[]],
    [[],[3],[0],[2],[],[],[],[],[],[],[],[],[],[],[]],
    [[],[],[],[1,3],[5],[],[],[4],[],[],[],[],[],[]],
    [[],[1],[0],[2,5],[],[],[],[],[],[],[10],[],[],[],[]],
    [[],[],[],[],[],[],[],[2],[],[],[3,5],[],[],[],[]],
    [[],[],[],[3],[0,2],[],[],[],[],[],[4],[],[],[],[],[]],
    [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]],
    [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]],
    [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]]

current_transmission_range = 0
transmission_range = np.zeros((len(nodes)), dtype=int)

pos = {x:[nodes[x][0],nodes[x][1]] for x in xrange(len(nodes))}
graph_nodes = [x for x in xrange(len(nodes))]


current_transmission_range = 0
cid = plt.gcf().canvas.mpl_connect('key_press_event', quit_figure)
plt.xlim(0,14)
plt.ylim(0,10)
plt.xticks([x+0.5 for x in xrange(0,14)], ['        '+str(x) for x in xrange(0,13)])
plt.yticks([x+0.5 for x in xrange(0,10)], ['\n\n'+str(x)+'\n\n\n\n' for x in xrange(0,9)])
plt.grid(True)

G = nx.Graph()
for node in graph_nodes:
    G.add_node(node)
for node in graph_nodes:
    for j in xrange(transmission_range[node]+1):
        for k in distance_array[node][j]:
            if(j <= current_transmission_range):
                G.add_edge(node, k,weight=j)

edge_weight=dict([((u,v,),int(d['weight'])) for u,v,d in G.edges(data=True)])
nx.draw_networkx_edge_labels(G, pos,edge_labels=edge_weight)
# draw graph
# nx.draw(G, pos)
plt.show()
2
Have you tried the hold argument?loopbackbee
Just tried it, didn't change anything. But I just saw theres an ax argument, that should probably help. Just have to figure out how exactlySimon

2 Answers

2
votes

Use plt.grid('on')

import networkx as nx
import matplotlib.pyplot as plt

G = nx.path_graph(4)
nx.draw_networkx(G)
plt.grid('on')
plt.show()

If you want to use nx.draw(G) instead of nx.draw_networkx(G) you must also turn on the axis with plt.axis('on').

enter image description here

0
votes

NetworkX's draw explicitly turns off axis.

You can avoid using draw and call the drawing subfunctions instead:

#...
nx.draw_networkx_nodes(G,pos)
nx.draw_networkx_edges(G,pos)
plt.show()

Or use draw_networkx, as Aric suggested.

That approach would be recommended if you're looking for long-term control over the drawing (as the draw implementation may change).

Of course, if it doesn't worry you, you can simply do plt.axes().set_axis_on() right after calling draw

enter image description here