I have a question which is similar to this question, but instead of plotting a very large number of points, I have fewer points and edges (factor of at least 10), but want to animate them. To be more specific, it is the visualization of a Kohonen network with a 2D-map, which evolves and looks like a deformed square lattic, see this image from Wikipedia:
Taken the code from this answer modified a bit, a minimal example looks like this:
import numpy as np
import matplotlib.pyplot as plt
def getXY(points, edges):
"""Return x and y arrays to pass to the plot function"""
return [points.T[i][edges.T] for i in np.arange(points.shape[1])]
points = numpy.array([[1,2],[4,5],[2,7],[3,9],[9,2]])
edges = numpy.array([[0,1],[3,4],[3,2],[2,4]])
lines = plt.plot(*getXY(points, edges), linestyle='-', color='y',
markerfacecolor='red', marker='o')
plt.show()
Then, an update happens which changes the points' coordinates:
points += 1 # simplified version of a real update
I would like to avoid the "stupid" way to replot everything, because there is other data in the plot window which does not change, also this is really slow:
# repeat after each update all the calculation
plt.cla()
x, y = [points.T[i][edges.T] for i in np.arange(points.shape[1])]
lines = plt.plot(x, y, linestyle='-', color='y',
markerfacecolor='red', marker='o')
plt.show()
As a first step, I saved the created Line2D data from the initial plot in the variable lines
.
The problem which I face now is that if I just want to update the lines data, the only solution which I could come up with requires me to iterate over all of the lines, which does not seem very elegant to me:
x, y = getXY(points, edges)
if len(lines) > 1:
for i, d in enumerate(zip(x.T, y.T)):
lines[i].set_data(d)
else: # has to be treated seperately, since the format of x and y is different
lines[0].set_data(x, y)
plt.show()
I am looking for suggestions how to...
- Come up with a better solution than my for-loop
- Ideas about how to solve the initial problem (plotting points with specified connections) in a more elegant way