title: Matplotlib + NetworkX - draw 2 networks in a single graphic
body: <p>If you know how to use Matplotlib, you are probably able to answer without knowing about NetworkX.</p>
  
  <p>I have 2 networks to draw using NetworkX, and I'd like to draw side by side in a single graphic, showing the axes of each. Essentially, it's a matter of creating 2 subplots in Matplotlib (which is the library that NetworkX uses to draw graphs).</p>
  
  <p>The positions of each node of the networks are distributed in an area of [0, area_size], but usually there is no point with coordinates x = 0.0 or y = area_size. That is, points appear inside an area of [0, area_size] or smaller. Not bigger.</p>
  
  <p>The proportions of each subgraph should be 0.8 x 1.0, separated by an area with proportions of 0.16 x 1.0.</p>
  
  <p>In essence, it should look like this (assuming area_size = 100).</p>
  
  <p><img src="https://i.stack.imgur.com/ZY7Es.png" alt="graphs with proportions"></p>
  
  <p>Then I have to draw lines between the 2 plots, so I need some way to get back to the positions in each graph, in order to connect them.</p>
  
  <p>Node positions are generated, stored and assigned like this</p>
  
  <pre><code># generate and store node positions
  positions = {}
  for node_id in G.nodes():
      pos_x = # generate pos_x in [0.0, area_size]
      pos_y = # generate pos_y in [0.0, area_size]
  
      positions[node_id]['x'] = pos_x
      positions[node_id]['y'] = pos_y
  
      G.node[node_id]['x'] = pos_x
      G.node[node_id]['y'] = pos_y
  </code></pre>
  
  <p>These positions are then stored in a dictionary <code>pos = {node_id: (x, y), ...}</code>. NetworkX gets this structure to draw nodes in the correct positions <code>nx.draw_network(G, pos=positions)</code>.</p>
  
  <p>Right now, I do the following:</p>
  
  <ul>
  <li>calculate the positions of the first network on the [0, area_size], then stretch them to [0, area_size*0.8]</li>
  <li>calculate the positions of the second network in the same way</li>
  <li>shift the positions of the second network to the right, summing area_size*0.8 + area_size*0.16 to the x coordinates</li>
  <li>set the figure size (in inches) <code>plt.figure(figsize=(h, w), dpi=100)</code></li>
  <li>set the x axis <code>plt.xlim(0.0, area_size*0.8*2 + area_size*0.16)</code></li>
  <li>set the y axis <code>plt.ylim(0.0, area_size)</code></li>
  <li>draw the first network (passing its positions)</li>
  <li>draw the second network (passing its positions)</li>
  <li>draw lines between the two networks</li>
  </ul>
  
  <p>The plot I get has the right proportions, but the axis does not display the right information. Should I hide the axis, and draw dummy ones?</p>
  
  <p>I probably need some better procedure to draw proper subplots.</p>
  
  <p>I also noticed that the figure size I set is not always respected when I export to pdf.</p>
  
  <p>The function NetworkX uses to draw a graph are <a href="https://networkx.github.io/documentation/latest/reference/drawing.html" rel="nofollow noreferrer">these</a>, in particular, I'm using <a href="https://networkx.github.io/documentation/latest/reference/generated/networkx.drawing.nx_pylab.draw_networkx.html#networkx.drawing.nx_pylab.draw_networkx" rel="nofollow noreferrer">draw_networkx</a>.</p>
  
  <p>I don't really mind drawing the separate axes, if they give too much trouble.</p>