Make an animation fade

I have managed to create an animation object, either through:

anim_ode = animate(ode_sol_1,kwargs...) #using a solution of a differential equation.
anim_macro = @animate for t_end in 0.:45
    plot(0.:0.1:t_end,t->(sin(t)*sqrt(t)),  xlims=(-10., 50), ylims=(-7., 7), grid=false, lw=6, color=3)
end #Using a loop and the @animate macro

I can display these animation all fine. However, is there a way to make the animation “fade”. Here I mean so the earliest part of the animated line have dissapeared by the time the final part is revealed. Currently the animation starts with none of the line displayed, and ends with 100% being displayed. Would it be possible to make it so that 100% is never shown.

An example of what I would liek to make. I want to display a circle being drawn. But I would like to make it look like a snake, 75% of the length of the circle circumference, is slowly snaking itself around in a circle. In principle if I could set a limit to how long a point is displayed, I could make this happen.

1 Like

I have been trying the following code, which should make a set of frames which only contains part of the circle circumference moving around:

using Plots

T = 12;
l = 0.1
L = 2;
anim = @animate for t_end in 0.:0.1:T
    t = max(0.,t_end-L):0.1:(t_end)
    x = sin.(t) 
    y = cos.(t) 

    plot(
        x, 
        y, 
        bg=:transparent, 
        grid=false, 
        xaxis=false, 
        yaxis=false, 
        legend=false,
        xlims=(-5, 5),
        ylims=(-5, 5),
        color=:red,
        linewidth = 5,
        size=(400,400)
        
    )
end

gif(anim,fps=10)

However, it does not seem to work. Halfway through the animation the full circle is filled, and stays like that. This is not the case if one looks at the individual frames. One can e.g. set t_end=4 and run:

t_end = 4
t = max(0.,t_end-L):0.1:(t_end)
x = sin.(t) 
y = cos.(t) 

plot(
    x, 
    y, 
    bg=:transparent, 
    grid=false, 
    xaxis=false, 
    yaxis=false, 
    legend=false,
    xlims=(-5, 5),
    ylims=(-5, 5),
    color=:red,
    linewidth = 5,
    size=(400,400)
)

which generates about the bottom third of the circle. This seems almost like a bug?

On further investigation there seem to be a problem with the argument bg=:transparent, removing this, and only having the other arguments in the first plot in the loop, seems to solve the issues.

2 Likes

Final update. While I have not found a way to directly add fade to a already created animation, it is possible with some proper micro-management of the @animate macro. For future reference, if anyone comes by interested in the same thing, this is an example where I do it. I create and animated plot of a christmas tree. I selectively only displays part of the solution to make it seem like some kind of fade. Could be made more advanced with proper use of linealpha and some more code.

# Fetches the requried packages.
using Plots
using DifferentialEquations #Required to make the star.
Plots.default(dpi=200)

#Sets parameters
n = 200;                                     # Number of points in each cycle.
f = 0.85;                                    # Fraction of points displayed
pts_disp = f*n;                              # The number of points displayed at every time.
N = 7;                                       #The number of cycles displayed (reduces the number of times there is a "hack" in the snow fall).
t = range(0.,2*π,length=n);                  # The time vector.

#Prepares the tree
width = 2
tree_length = 8.5π
y = Array(range(0,tree_length,length=n))
x = width*sin.(y).*sqrt.(y)
Tree = (x,y[end:-1:1]);

#Prepares a ball
x = sin.(t[1:end-2])
y = cos.(t[1:end-2])
Ball = ([x...,x[1],x[2]],[y...,y[1],y[2]]);

#Prepares the root
r_length = tree_length/10;
y = Array(range(0,r_length,length=n))[end:-1:1]
x = zeros(n)
Root = (x,y.-tree_length/20);

#Prepares the star
star_size = 0.7
R = star_size*5.;     # Hypotrochoid parameter.
r = star_size*3.;     # Hypotrochoid parameter.
d = star_size*3.;     # Hypotrochoid parameter.
function star(du,u,p,t)
 du[1] = (p[1]-p[2])*cos(t)+p[3]*cos(t*(p[1]-p[2])/p[2])
 du[2] = (p[1]-p[2])*sin(t)-p[3]*sin(t*(p[1]-p[2])/p[2])
end;
u0 = [R-r+d,0.]
tspan = (0., 6*π)
p = [R,r,d]
prob = ODEProblem(star,u0,tspan,p)
sol_star = solve(prob,dtmax=0.2,saveat=range(0.,6*π,length=(n-2)));
x = first.(sol_star.u).-R
y = last.(sol_star.u).+tree_length.+r
Star = ([x...,x[1],x[2]],[y...,y[1],y[2]]);

#Stacks up the designated number of cycles
for object in [Tree, Ball, Root, Star]
    cpy = deepcopy(object)
    for i = 2:N 
        append!(object[1],cpy[1])
        append!(object[2],cpy[2])
    end
end

#Define the plotting area
x0 = -25; x1 = -x0;
y0 = -5; y1 = 40;
sx = 400;
sy = sx*(y1-y0)/(x1-x0);


#Let it snow
n_snow = 50
x_snow = x1 .* 2 .* (0.5 .- rand(n_snow))
y_snow = (y1 - y0) .* rand(n_snow) .+ y0
function move_y_snow(y_snow, movements, ylims) 
    y_snow .-= movements
    for i in eachindex(y_snow)
        if y_snow[i] < ylims[1]
            y_snow[i] = ylims[2]
        end
    end
end
function move_x_snow(x_snow, additions, xlims) 
    x_snow .+= additions
    for i in eachindex(y_snow)
        if x_snow[i] > xlims[2]
            x_snow[i] -= xlims[2] - xlims[1]
        elseif y_snow[i] < xlims[1]
            x_snow[i] += xlims[2] - xlims[1]
        end
    end
end;

#Makes the animation
anim = @animate for t_end1 in 1:n*N
    t_end1 = t_end1%n
    (t_end1==0)&&(t_end1=1)
    t_start1 = Int(max(1,t_end1-pts_disp)) 
    t_start2 = Int(t_end1+n-pts_disp)
    t_end2 = Int(min(t_start2+pts_disp-t_end1+t_start1,n))
    plot(xlims=(x0, x1), ylims=(y0, y1),size=(sx,sy), legend=false)
    plot!(xaxis=false,yaxis=false, grid=false, legend=false,linewidth=5)
    
    
    y_rate = 0.5
    x_rate = 0.5
    move_y_snow(y_snow, y_rate .* rand(n_snow), (y0, y1))
    move_x_snow(x_snow, x_rate .* (0.5 .- rand(n_snow)), (x0, x1))
    scatter!(x_snow, y_snow, ms=8, markershape=:star6, color=:white)
    
    lw_tree = 7
    plot!(Tree[1][t_start1:t_end1],Tree[2][t_start1:t_end1],color=:green, linewidth=lw_tree) 
    plot!(Tree[1][t_start2:t_end2],Tree[2][t_start2:t_end2],color=:green,linewidth=lw_tree)
    plot!(Star[1][t_start1:t_end1],Star[2][t_start1:t_end1],color=:yellow,linewidth=lw_tree)
    plot!(Star[1][t_start2:t_end2],Star[2][t_start2:t_end2],color=:yellow,linewidth=lw_tree)
    
    lw_ball = 9
    plot!(Ball[1][t_start1:t_end1].-8,Ball[2][t_start1:t_end1].+2.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start2:t_end2].-8,Ball[2][t_start2:t_end2].+2.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start1:t_end1].+8,Ball[2][t_start1:t_end1].+5.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start2:t_end2].+8,Ball[2][t_start2:t_end2].+5.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start1:t_end1].-6.5,Ball[2][t_start1:t_end1].+9,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start2:t_end2].-6.5,Ball[2][t_start2:t_end2].+9,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start1:t_end1].+5,Ball[2][t_start1:t_end1].+12,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start2:t_end2].+5,Ball[2][t_start2:t_end2].+12,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start1:t_end1].-3.75,Ball[2][t_start1:t_end1].+15.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start2:t_end2].-3.75,Ball[2][t_start2:t_end2].+15.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start1:t_end1].+3.25,Ball[2][t_start1:t_end1].+18.5,color=:red,linewidth=lw_ball)
    plot!(Ball[1][t_start2:t_end2].+3.25,Ball[2][t_start2:t_end2].+18.5,color=:red,linewidth=lw_ball)
    
    lw_root = 20
    plot!(Root[1][t_start1:t_end1],Root[2][t_start1:t_end1],color=:brown,linewidth=lw_root)
    plot!(Root[1][t_start2:t_end2],Root[2][t_start2:t_end2],color=:brown,linewidth=lw_root)
    
    plot!(bg_color=:black)
end;

#Displays/saves the animation
gif(anim,"christmas_tree.gif",fps = 40)
1 Like