0

I use Windows 10 / 64 / Google chrome

I found a good set-up for animation over Jupyter with the call %matplotlib notebook as here :

import numpy as np
import scipy.stats as st
%matplotlib notebook
import matplotlib.pyplot as plt
import matplotlib.animation as animation

For exemple, this one is working pretty well :

n = 100
X = st.norm(0,1).rvs(200)
number_of_frames = np.size(X)

def update_hist(num, second_argument):
    plt.cla()
    plt.hist(X[:num], bins = 20)
    plt.title("{}".format(num))
    plt.legend()

fig = plt.figure()
hist = plt.hist(X)

ani = animation.FuncAnimation(fig, update_hist, number_of_frames, fargs=(X, ), repeat = False )
plt.show()

But, weirdly the code below doesn't work while it's the same structure, it puzzles me :

X = np.linspace(-5,5, 150)
number_of_frames = np.size(X)
N_max = 100
N = np.arange(1,N_max+1)
h = 1/np.sqrt(N)

def update_plot(n, second_argument):
    #plt.cla()
    plt.plot(X, [f(x) for x in X], c = "y", label = "densité")
    plt.plot(X, [fen(sample_sort[:n],h[n],x) for x in X], label = "densité")
    plt.title("n = {}".format(n))

fig = plt.figure(6)
plot = plt.plot(X, [f(x) for x in X], c = "y", label = "densité")
    
ani = animation.FuncAnimation(fig, update_plot, number_of_frames, fargs=(X, ), repeat = False )
plt.show()

Thanks for your help, best regards.

EDIT : You don't have the funciton fen(sample_sort[:n],h[n],x) it is a function from float to float taking a x in argument and returning a flot. The argument sample_sort[:n],h[n] it is just maths things I'm trying to understand some statistics anyway, you can remplace with line with what you want np.cos(N[:n]) for exemple.

EDIT : New code according to the suggestion :

N_max = 100
X = np.linspace(-5,5, N_max )
number_of_frames = np.size(X)
N = np.arange(1,N_max+1)
h = 1/np.sqrt(N)

def update_plot(n):
    #plt.cla()
    lines.set_data(X, np.array([fen(sample_sort[:n],h[n],x) for x in X]))
    ax.set_title("n = {}".format(n))
    return lines

fig = plt.figure()

ax = plt.axes(xlim=(-4, 4), ylim=(-0.01, 1))
ax.plot(X, np.array([f(x) for x in X]), 'y-', lw=2, label="d")
lines, = ax.plot([], [], 'b--', lw=3, label="f")

ani = animation.FuncAnimation(fig, update_plot, number_of_frames, repeat = False )
plt.show()

EDIT 2:

I found a code over internet which does exactly what I would like

# Fermi-Dirac Distribution
def fermi(E: float, E_f: float, T: float) -> float:
    return 1/(np.exp((E - E_f)/(k_b * T)) + 1)

# Create figure and add axes
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111)

# Get colors from coolwarm colormap
colors = plt.get_cmap('coolwarm', 10)

# Temperature values
T = np.array([100*i for i in range(1,11)])

# Create variable reference to plot
f_d, = ax.plot([], [], linewidth=2.5)

# Add text annotation and create variable reference
temp = ax.text(1, 1, '', ha='right', va='top', fontsize=24)

# Set axes labels
ax.set_xlabel('Energy (eV)')
ax.set_ylabel('Fraction')

# Animation function
def animate(i):
    x = np.linspace(0, 1, 100)
    y = fermi(x, 0.5, T[i])
    f_d.set_data(x, y)
    f_d.set_color(colors(i))
    temp.set_text(str(int(T[i])) + ' K')
    temp.set_color(colors(i))

# Create animation
ani = animation.FuncAnimation(fig, animate, frames=range(len(T)), interval=500, repeat=False)

# Ensure the entire plot is visible
fig.tight_layout()

# show animation
plt.show()
CechMS
  • 140
  • 10
  • 1
    There also is a function f() not defined, what sort of error does the code return? – Jayvee May 03 '21 at 08:02
  • Indeed ! You can choose f = np.cos. And there's no error but the thing is there's no animation, I only get the plot : plot = plt.plot(X, [f(x) for x in X], c = "y", label = "densité") – CechMS May 03 '21 at 08:04
  • `lines.set_data(X, np.array([fen(sample_sort[:n],h[n],x) for x in X]))`In the animation function, the length of X and Y need to be the same, so it should be `X[:n]`. – r-beginners May 03 '21 at 13:41

1 Answers1

3

What I want to draw is a curve at random because the actual state of the function is unknown. The basic structure looks like this, so please modify it based on this.

import numpy as np
import scipy.stats as st
# %matplotlib notebook
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# from IPython.display import HTML
# from matplotlib.animation import PillowWriter

X = np.linspace(-5,5, 100)
number_of_frames = np.size(X)
N_max = 100
N = np.arange(1,N_max+1)
h = 1/np.sqrt(N)

def update_plot(n):
    #plt.cla()
    lines.set_data(X[:n], h[:n])
    lines2.set_data(X[:n], h[:n]*-1)
    ax.set_title("n = {}".format(n))
    return lines, lines2

fig = plt.figure()
ax = plt.axes(xlim=(-5, 5), ylim=(-1, 1))
lines, = ax.plot([], [], 'y-', lw=2, label="densité")
lines2, = ax.plot([], [], 'b--', lw=3, label="densité2")

ani = animation.FuncAnimation(fig, update_plot, frames=number_of_frames, repeat=False )
plt.show()
# ani.save('lines_ani2.gif', writer='pillow')

# plt.close()
# HTML(ani.to_html5_video())

enter image description here

r-beginners
  • 31,170
  • 3
  • 14
  • 32
  • Cheers, I fancy : ax.set_title("n = {}".format(n)) in your code because even if you return lines, lines2 your function still provide a legend. Your code works on my laptop. – CechMS May 03 '21 at 08:43
  • But mine still doesn't work, I add it in the first post. It means I have a empty figure – CechMS May 03 '21 at 08:44
  • 1
    X is set to 150, but x and y need to be the same, so I set mine to 100. – r-beginners May 03 '21 at 08:52
  • 1
    Also, you need to set the drawing range of the graph, so you need to modify it to the range of your function. `ax = plt.axes(xlim=(-5, 5), ylim=(-1, 1))` – r-beginners May 03 '21 at 09:00
  • It shouldn't be a problem as my f takes place as plt.axes(xlim=(-4,4), ylim=(0, 0.6)) – CechMS May 03 '21 at 09:04
  • I edited my post taking your suggestions into my code. It is unfortunaly still the same, there's one thing to notice our code are not exactly the same. I plot for each n two function f and f_n and then my animation shows how f_n evolves in time. I know it doesn't really matter for our bugs but it is still worth to notice. – CechMS May 03 '21 at 09:07
  • I deleted : fargs=(X, ) and then the yellow plot came in ! I'm getting closer the need the blue plot now :D – CechMS May 03 '21 at 09:13
  • About X, I've tried T = np.array([fen(sample_sort[:1],h[1],x) for x in X]) print(T.shape) It is (100,) – CechMS May 03 '21 at 09:16
  • This is the fundamental logic of animation, and the n of the animation function is the key. So, we draw the data obtained by sequentially counting up n. In the code you have added, n is not working. – r-beginners May 03 '21 at 09:54
  • Adding EDIT 2 in the first post – CechMS May 03 '21 at 11:28
  • Let's first understand the difference between your code `lines.set_data(X, np.array([f(x) for x in X]))` and my code `lines.set_data(X[:n], h[:n])`. – r-beginners May 03 '21 at 12:45
  • My line doesn't involve n – CechMS May 03 '21 at 12:48
  • So what do you animate? – r-beginners May 03 '21 at 12:49
  • Even if I delete the line it does still not work. – CechMS May 03 '21 at 12:50
  • I animate the second line lines2, lines was just a background I deleted it to check if it works it doesn't – CechMS May 03 '21 at 12:51
  • The animation function has only the target to update the data sequentially. If you want to display the data from the beginning, place it outside the animation function. Also, have you checked the data that will be created in your lines2? For example, is the output `print(np.array([fen(sample_sort[:n],h[n],x))` as intended? Also, is it possible to draw it as a normal graph? – r-beginners May 03 '21 at 12:56
  • np.array([fen(sample_sort[:n],h[n],x) for x in X]) is (100,) array – CechMS May 03 '21 at 13:21
  • np.array([fen(sample_sort[:n],h[n],x) for x in X]) can be ploted indeed, it's a nice graph for n = 2 but I check for n until 10000 it's okay – CechMS May 03 '21 at 13:22
  • That's a step in the right direction. What part of that graph do you want to animate? – r-beginners May 03 '21 at 13:26
  • I have made the changes you advice me, update doesn't work but I have a yellow graph – CechMS May 03 '21 at 13:26
  • I would like to animate like this : Plot x, step 1 plot x/2, step 2 plot x/3 ... step n plot x/(n+1) you will see an animation for x/n converges to 0 – CechMS May 03 '21 at 13:29
  • If you want to animate a decreasing number, you can just do `n*-1`. – r-beginners May 03 '21 at 13:32
  • Yeah I should give up for now. – CechMS May 03 '21 at 13:46
  • I can't ask an other question with my account :'( – CechMS May 03 '21 at 16:36
  • I mean as a completely new question. – r-beginners May 04 '21 at 02:13
  • I've reached the maximum questions I can ask for a while. – CechMS May 04 '21 at 07:07
  • Was there a limit to the number of questions here(SO)? – r-beginners May 04 '21 at 07:09
  • I have no answer sir – CechMS May 04 '21 at 07:12