Gaizka Garmendia
Gaizka Garmendia

Reputation: 15

Animated Scatter Plot

I would like to do an animation in python representing each point, dot by dot. I am doing it as I always have done it, but it does not work. Any help? I tried 2 different ways.

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

%matplotlib nbagg

def mcd(a, b):
    resto = 0
    while(b > 0):
        resto = b
        b = a % b
        a = resto
    return a

N = 1200

n = list (range (N))
an = [1,1]

for i in range (2,N):
    k = i-1
    if mcd (n[i], an[k]) == 1:
        an.append (n[i] + 1 + an[k])
    else:
        an.append (an[k]/mcd (n[i], an[k]))

fig = plt.figure ()
ax = fig.add_subplot (111)
ax.grid (True)
ax.set_xlim(0, N*1.1)
pt, = ax.plot ([],[],'ko', markersize=2)

ax.plot (n,an, 'ko', markersize=2)

def init ():

    pt.set_data([],[])
    return (pt)

def animate (i,pt):

    pt.set_data (n[:i],an[:i])

    return (pt)

ani = FuncAnimation (fig, animate, fargs = (pt), frames=N, init_func=init, interval=50, blit = True)

plt.show ()

And the second way:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

%matplotlib nbagg

def mcd(a, b):
    resto = 0
    while(b > 0):
        resto = b
        b = a % b
        a = resto
    return a

N = 1200

n = list (range (N))
an = [1,1]

for i in range (2,N):
    k = i-1
    if mcd (n[i], an[k]) == 1:
        an.append (n[i] + 1 + an[k])
    else:
        an.append (an[k]/mcd (n[i], an[k]))

xdata, ydata = [],[]

fig = plt.figure ()
ax = fig.add_subplot(111)
ax.grid (True)
pt, = ax.plot ([],[],'ko', markersize=2)

ax.plot (n,an, 'ko', markersize=2)

def init ():
    ax.set_xlim(0, N*1.1)
    pt.set_data([],[])
    return (pt)

def animate (pt):
    xdata.append (n[i])
    ydata.append (an[i])

    pt.set_data (xdata,ydata)

    return (pt)

ani = FuncAnimation (fig, animate, fargs = (pt), frames=N, init_func=init, interval=50, blit = True)

plt.show ()

Using those codes, I get the entire figure with all the points. I would like to fill the graph point by point in an animated way.

Upvotes: 0

Views: 1346

Answers (2)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339630

The following will work

%matplotlib nbagg
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def mcd(a, b):
    resto = 0
    while(b > 0):
        resto = b
        b = a % b
        a = resto
    return a

N = 1200

n = list (range (N))
an = [1,1]

for i in range (2,N):
    k = i-1
    if mcd (n[i], an[k]) == 1:
        an.append (n[i] + 1 + an[k])
    else:
        an.append (an[k]/mcd (n[i], an[k]))

fig = plt.figure ()
ax = fig.add_subplot (111)
ax.grid (True)
ax.set_xlim(0, N*1.1)
ax.set_ylim(min(an), max(an))
pt, = ax.plot([],[],'ko', markersize=2)

def init ():
    pt.set_data([], [])
    return pt,

def animate(i):
    pt.set_data (n[:i], an[:i])
    return pt,

ani = FuncAnimation (fig, animate, frames=N, init_func=init, interval=50, blit = True)

plt.show ()

enter image description here

Upvotes: 2

furas
furas

Reputation: 143002

EDIT: I tested it in normal Python Shell and it draws black dots on red dots but Jupyter draws black dots hidden behind red dots so it needs these lines in different order - first red dots, next empty plot for black dots.

ax.plot(n, an, 'ro', markersize=2) # red dots
pt, = ax.plot([], [], 'ko', markersize=2)

First: I get error message

 TypeError: 'Line2D' object is not iterable. 

All because () doesn't create tuple - you have to use comma , to create tuple in return pt, and fargs=(pt,)


Problem is because you draw all point at start using

ax.plot(n, an, 'ko', markersize=2)

and later it draws dots in the same places so you don't see animation.

If you use different color - ie. red

ax.plot(n, an, 'ro', markersize=2)

then you will see animation of black points on red points.

enter image description here

Or remove this line and it will draw dots in empty window.

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

#%matplotlib nbagg

def mcd(a, b):
    resto = 0
    while(b > 0):
        resto = b
        b = a % b
        a = resto
    return a

N = 1200

n = list(range(N))
an = [1, 1]

for i in range(2, N):
    k = i-1
    if mcd(n[i], an[k]) == 1:
        an.append(n[i] + 1 + an[k])
    else:
        an.append(an[k]/mcd(n[i], an[k]))

fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid(True)
ax.set_xlim(0, N*1.1)
pt, = ax.plot([], [], 'ko', markersize=2)

ax.plot(n, an, 'ro', markersize=2) # red dots

def init():
    pt.set_data([], [])
    return (pt,)

def animate(i, pt):
    pt.set_data(n[:i], an[:i])
    return (pt,)


ani = FuncAnimation(fig, animate, fargs=(pt,), frames=N, init_func=init, interval=50, blit=True)

plt.show ()

In second code you have the same problems and you also forgot i in def animate(i, pt):

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

#%matplotlib nbagg

def mcd(a, b):
    resto = 0
    while(b > 0):
        resto = b
        b = a % b
        a = resto
    return a

N = 1200

n = list(range (N))
an = [1, 1]

for i in range(2, N):
    k = i-1
    if mcd(n[i], an[k]) == 1:
        an.append(n[i] + 1 + an[k])
    else:
        an.append(an[k]/mcd (n[i], an[k]))

xdata, ydata = [], []

fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid(True)
pt, = ax.plot([], [], 'ko', markersize=2)

ax.plot(n, an, 'ro', markersize=2)

def init():
    ax.set_xlim(0, N*1.1)
    pt.set_data([], [])
    return (pt,)

def animate(i, pt):
    xdata.append(n[i])
    ydata.append(an[i])

    pt.set_data(xdata, ydata)

    return (pt,)

ani = FuncAnimation(fig, animate, fargs=(pt,), frames=N, init_func=init, interval=50, blit=True)

plt.show ()

Upvotes: 1

Related Questions