Matplotlib 修复赛璐珞创建的动画中的图例

Matplotlib 修复赛璐珞创建的动画中的图例,matplotlib,animation,legend,celluloid,Matplotlib,Animation,Legend,Celluloid,我想通过不同的梯度下降优化方法来模拟寻找函数最小点的过程。为此,我使用matplotlib和赛璐珞包。问题在于,无法修复动画中的绘图图例,并且在每个循环中,都会在先前图例的下方添加一个新图例,如下图所示。有没有办法修复图例并避免此问题 from celluloid import Camera fig,ax = plt.subplots(1, 1,figsize=(10, 10)) camera = Camera(fig) for i in range(path1.shape[1]) ax.c

我想通过不同的梯度下降优化方法来模拟寻找函数最小点的过程。为此,我使用matplotlib和赛璐珞包。问题在于,无法修复动画中的绘图图例,并且在每个循环中,都会在先前图例的下方添加一个新图例,如下图所示。有没有办法修复图例并避免此问题

from celluloid import Camera
fig,ax = plt.subplots(1, 1,figsize=(10, 10))
camera = Camera(fig)
for i in range(path1.shape[1])
  ax.contour(x_mesh, y_mesh, z, levels=np.logspace(0, 5, 35), norm=LogNorm(), cmap=plt.cm.jet)
  ax.plot(*minima_, 'r*', markersize=18)

  line, = ax.plot([], [], 'k', label='Simple SGD', lw=2)
  point, = ax.plot([], [], 'ko')
  line.set_data(path1[::,:i])
  point.set_data(path1[::,i-1:i])

  line, = ax.plot([], [], 'r', label='SGD with momentum', lw=2)
  point, = ax.plot([], [], 'ro')
  line.set_data(*path2[::,:i])
  point.set_data(*path2[::,i-1:i])

  line, = ax.plot([], [], 'g', label='SGD with Nesterov', lw=2)
  point, = ax.plot([], [], 'go')
  line.set_data(*path3[::,:i])
  point.set_data(*path3[::,i-1:i])

  line, = ax.plot([], [], 'b', label='SGD with Adagrad', lw=2)
  point, = ax.plot([], [], 'bo')
  line.set_data(*path4[::,:i])
  point.set_data(*path4[::,i-1:i])

  line, = ax.plot([], [], 'c', label='SGD with Adadelta', lw=2)
  point, = ax.plot([], [], 'co')
  line.set_data(*path5[::,:i])
  point.set_data(*path5[::,i-1:i]) 

  line, = ax.plot([], [], 'm', label='SGD with RMSprob', lw=2)
  point, = ax.plot([], [], 'mo')
  line.set_data(*path6[::,:i])
  point.set_data(*path6[::,i-1:i])

  line, = ax.plot([], [], 'y', label='SGD with Adam', lw=2)
  point, = ax.plot([], [], 'yo')
  line.set_data(*path7[::,:i])
  point.set_data(*path7[::,i-1:i])

  line, = ax.plot([], [], 'y', label='SGD with Adamax', lw=2)
  point, = ax.plot([], [], 'y*')
  line.set_data(*path8[::,:i])
  point.set_data(*path8[::,i-1:i])

  line, = ax.plot([], [], 'k', label='SGD with Nadam', lw=2)
  point, = ax.plot([], [], 'kp')
  line.set_data(*path9[::,:i])
  point.set_data(*path9[::,i-1:i])

  line, = ax.plot([], [], 'r', label='SGD with AMSGrad', lw=2)
  point, = ax.plot([], [], 'rD')
  line.set_data(*path10[::,:i])
  point.set_data(*path10[::,i-1:i])

  ax.legend(loc='upper left') 
  camera.snap()
animation = camera.animate()
animation.save('2D_animation_overlap.gif', writer='imagemagick')

这里的最佳实践是创建自定义图例,而不是自动生成图例,在这种情况下,可以通过

导入matplotlib.pyplot作为plt
从matplotlib.lines导入Line2D
标签=['单一新加坡元','动量新加坡元','内斯特罗夫新加坡元',
“新加坡元与Adagrad”、“新加坡元与Adadelta”、“新加坡元与RMSprob”、“新加坡元与Adam”,
“SGD与Adamax”、“SGD与Nadam”、“SGD与AMSgrad”]
颜色=['k',r',g',b',c',m',y',y',k',r']
句柄=[]
对于拉链中的c、l(颜色、标签):
handles.append(Line2D([0],[0],color=c,label=l))
plt.图例(手柄=手柄,位置=左上角)
这将给你一个这样的传奇:

你不需要在循环中有任何这些,你可以在之前或之后做,它仍然可以工作。它也将在循环中工作,但每次都重新绘制图例是不必要的

只需使用if语句来保护图例的创建,而不是手动创建图例就足够了。即

#。。。
如果i==0:
ax.图例(位置=‘左上’)

但是我建议不要刺激自动传奇生成,而直接创建传奇。

那么你想要动画而不仅仅是情节?在动画中固定了图例,没有重复,正如我在这里看到的。是的,完全正确。你有没有想法创造这样一个固定的传说?有一个很好的例子。看看这是否有帮助。另外,我无法编译你发布的代码。你能发布一个工作代码吗?对不起,我的代码太长,无法在这里发布。如果你愿意,我可以通过电子邮件发送给你。然而,威廉的回答解决了我的问题。非常感谢你,威廉。您的第二个答案非常有用,解决了我的问题。@hamidmohebzadeh很高兴它有帮助,请务必将其标记为该问题,以便将来的用户使用