1

I'm working on a network project in which I need to draw lines (edges) between pairs of points (nodes). Currently I'm using matplotlib.pyplot for this, but the problem is that pyplot.plot(x, y) starts at (x[0], y[0]) and then continues to (x[1], y[1]) etc.
I have a separate list of tuples for the connections of the nodes:
edges=[(0,1), (0,2), (3,2), (2,1)...(m,n)], which refers to indices of the separate nodes. The problem is that I need to animate the thing with matplotlib.animation.

To just add lines between nodes (static picture) I was using ax.add_line(Line2D([x1, x2], [y1, y2])), but I can't figure out how to get this method to work with animation.FuncAnimation().

Some dummy code:

import matplotlib.pyplot as plt

edges = [(0,1), (2,3), (3,0), (2,1)]

x = [-5, 0, 5, 0]
y = [0, 5, 0, -5]

lx = []
ly = []
for edge in edges:
    lx.append(x[edge[0]])
    lx.append(x[edge[1]])
    ly.append(y[edge[0]])
    ly.append(y[edge[1]])

plt.figure()
plt.plot(x, y, 'ro')
plt.plot(lx, ly, '-', color='#000000')
plt.show()

(Image of this and the next example below)

If I instead use the following:

import matplotlib.pyplot as plt
from pylab import Line2D, gca

edges = [(0,1), (2,3), (3,0), (2,1)]

x = [-5, 0, 5, 0]
y = [0, 5, 0, -5]

plt.figure()
ax = gca()
for edge in edges:
    ax.add_line(Line2D([x[edge[0]], x[edge[1]]], [y[edge[0]], y[edge[1]]], color='#000000'))

ax.plot(x, y, 'ro')
plt.show()

it all works the way I need: Examples.
Unfortunately, this is not possible (afaik) during animation. What I need then is is a way to plot lines between individual pairs of nodes.

Very bad problem formulation, I know, but I hope that someone understands and is able to help.

Thank you!

user2591113
  • 11
  • 1
  • 2

1 Answers1

1
>>> edges=[(0,1), (0,2), (3,2), (2,1)]
>>> 
>>> xx = [x[0] for x in edges]
[0, 0, 3, 2]
>>> yy = [x[1] for x in edges]
[1, 2, 2, 1]
>>> line, = ax.plot(xx, yy, 'ro-')

Then just feed this to plot and animate the result. Here's one example (there are many).

ev-br
  • 24,968
  • 9
  • 65
  • 78
  • Hmm, this is not what I was after.. The FuncAnimation requires an animate function, def animate(i), which has to return a list of objects to be drawn. I can return the coordinates of all the nodes, which shows up correctly (ofc). However, I need a way (somehow) to return a list of lines (or equivalent), which when plotted only will connect two of the points. All the ways I've tried so far draws a continuous sequence of lines between all x/y in the list. As I said, hmm... – user2591113 Jul 17 '13 at 13:10
  • I don't understand. You have a list of nodes. You draw the edges between them. Now, what is that you're trying to animate: what changes from frame to frame? – ev-br Jul 17 '13 at 13:29
  • Yeah, the problem is the list of lines between nodes. I implemented a force directed algorithm for graph layout, and want to see it "evolve". The problem is that if a node has multiple edges, the ax.plot(x, y, '-') wont cut it, since it starts at x[0],y[0] and then goes to x[1],y[1]. Say that edges = [(0,2), (1,3)], ax.plot draws a line from x/y corresponding to node 0 and 2, which is good. However, it then draws from 2 to 3, an edge that does not exist. – user2591113 Jul 17 '13 at 13:40
  • 1
    Please clarify your input format: for edges = [(0,2), (1,3)] what is (0,2): are these the coordinates of the first edge (x=0, y=2), or is it an edge between vertices 0 and 2 (in which case: what are the coordinates of these vertices)? Probably the best is to edit this into the question. – ev-br Jul 17 '13 at 14:01
  • You have understood it correctly; the (0,2) refers to the nodes indexed 0 and 2, respectively. Thanks for all your help! – user2591113 Jul 17 '13 at 14:38
  • and where do coordinates of these nodes come from? – ev-br Jul 17 '13 at 14:44
  • The Node class has the coordinates stored as members (x and y), as well as index. So (nodes[0].x, nodes[0].y) refers to the coords of the first node. !!! for e in edges: (nodes[e[0]].x, nodes[e[1]].x) !!! gives me the x coordinates for both nodes connected by the egde e. – user2591113 Jul 17 '13 at 14:47
  • Then all you need to do is to just iterate over the list of your edges, form the two lists of coordinates for the nodes, and feed it to the `plot`, storing the line instance it returns. When animating, use its `set_data` method. – ev-br Jul 17 '13 at 14:50