由边连接的点的动画图

时间:2012-02-23 15:31:35

标签: python matplotlib

我有一个类似于这个question的问题,但是我没有绘制大量的点,而是有更少的点和边(因子至少为10),但想要为它们设置动画。更具体地说,它是具有2D地图的Kohonen网络的可视化,其发展并且看起来像变形的方形网格,参见来自维基百科的图像:

image

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()

然后,更新发生了更改点'坐标:

points += 1 # simplified version of a real update

我想避免"愚蠢的"重新绘制所有内容的方法,因为绘图窗口中的其他数据没有变化,这也很慢:

# 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()

作为第一步,我从变量lines中的初始图中保存了创建的Line2D数据。 我现在面临的问题是,如果我只想更新行数据,我能想出的唯一解决办法就是要遍历所有行,这对我来说似乎不太优雅:

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()

我正在寻找建议如何......

  • 提出比我的for-loop更好的解决方案
  • 关于如何以更优雅的方式解决初始问题(使用指定连接绘制点)的想法

1 个答案:

答案 0 :(得分:0)

这是一种可行的方法。您可以使用以下事实:如果在线的坐标中存在NaN或无,则将其视为线段的末端。下一个非None点被视为新段的开头。

import numpy as np, matplotlib.pyplot as plt
x,y = np.array([1, 4,2, 3, 9]), np.array([2, 5, 7, 9, 2])

edges = np.array([[0, 1],
   [3, 4],
   [3, 2],
   [2, 4],
   [2, 1]])

ys=np.vstack((y[edges[:,0]],y[edges[:,1]],y[edges[:,0]]+np.nan)).T.flatten()

xs=np.vstack((x[edges[:,0]],x[edges[:,1]],x[edges[:,0]]+np.nan)).T.flatten()

lines2d = plt.plot(xs,ys,marker='o')

现在为了更新坐标(例如,将x轴移动.1和y轴除以.2,你可以做到:

oldx,oldy=lines2d[0].get_data()
lines2d[0].set_data(oldx+.1,oldy+.2)
plt.draw()

PS我不完全确定我在xs,ys数组中插入Nans的方式是最快的,但它可能并不重要。