-1

Note: this is not about "animating" charts; rather, updating and extending the data of the plot.

I have seen a lot of PyPlot S.O. questions about how to update PyPlot in a loop, but many of these answers either outdated, or beyond the simplicity I seek.

The closest example I have seen is this:

import pylab as pl
from IPython import display
for i in range(10):
    pl.plot(pl.randn(100))
    display.clear_output(wait=True)
    display.display(pl.gcf())

but it plots new data on top of the old at each loop iteration and when finished, produces two charts, where I only want one.

enter image description here

So lets say I have two lines:

l1 = [i for i in range(10)]
l2 = [i^2 for i in range(10)]

and I am going to add new data to each line at each loop iteration:

for i in range(11, 20):
    l1.append(i)
    l2.append(i^2)

all I want is to see a single plot that is showing the updated lines.

some posts suggest using the set_ydata function of a subplot, but this doesnt seem to work for me. Example from https://stackoverflow.com/a/4098938/5623899

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
    line1.set_ydata(np.sin(x + phase))
    fig.canvas.draw()

only produces the plot once the entire thing is done.

changing that example towards the one I postulated fails

l1 = [i for i in range(10)]
l2 = [i^2 for i in range(10)]
print([i^2 for i in range(10)])
print(l2)
import pylab as pl
from IPython import display

fig = plt.figure()
ax = fig.add_subplot(111)

line1 = ax.plot(l1)
line2 = ax.plot(l2)

for i in range(11, 20):

    l1.append(i)
    l2.append(i^2)

    line1.set_ydata(l1)
    line2.set_ydata(l2)

    fig.canvas.draw()

as having only a singluar array in plt.plot(arr) results in the method set_ydata not being present.

so how do I do this?

SumNeuron
  • 4,850
  • 5
  • 39
  • 107
  • The code from the question does only produce one chart if I run it. The fact that all the lines are adding up has little to do with the animation, use `plt.gca().clear()` to clear the axes in each step. I would hence agree that this is a duplicate, unless the question makes the problem of the approach absolutely clear. – ImportanceOfBeingErnest Oct 23 '17 at 11:21
  • @ImportanceOfBeingErnest I am not doubting the results you received. However, there is no doubt that in the jupyter notebook I am running, that following the final iteration of the loop, I end up with two graphs. Using the code above, it will simply plot a new line on top of the old one, change the color. This is what the quesiton was about, avoiding this – SumNeuron Oct 23 '17 at 11:42
  • So those are two different problems. The solution to removing the old lines from the plot has nothing to do with the animation and it is to add `plt.gca().clear()`. You could also use `set_ydata` to update the plot; "but this doesnt seem to work" is not a sufficient problem description). The problem of two plots appearing may be there, but it's not apparent from the question - include the versions in use and a screenshot. – ImportanceOfBeingErnest Oct 23 '17 at 12:03
  • @ImportanceOfBeingErnest I have added more clarification as you suggested – SumNeuron Oct 23 '17 at 13:29
  • It seems you are completely ignoring `plt.gca().clear()`, so here it is a third time. Also, none of your attemps actually use `display`, which is the thing that makes your figures be shown several times. An alternative to a loop with `display` is to use `FuncAnimation` to which there is also several answers around. – ImportanceOfBeingErnest Oct 23 '17 at 13:40

1 Answers1

1

I don't know why people have reopened this question, but it is of course still a duplicate of Animation in iPython notebook. Just claiming not to want an animation does not mean that it is not an animation that is asked for here. The answers there give several options, and yes using display will result in the last frame being outputted twice if run in a single cell; other solutions dont have this problem - so it would be wise to use any of the other solutions.

Just to correct the example here for what is mentionned in the comments (plt.gca().clear()):

import pylab as pl
from IPython import display
for i in range(10):
    pl.plot(pl.randn(100))
    display.clear_output(wait=True)
    display.display(pl.gcf())
    plt.gca().clear()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712