Pandas Read CSV and animate the data

From wikiluntti

Introduction

Read CSV data, filter, interpolate and smooth it, and the animate the plotting. The file is File:Convergence dataOnly.csv.

Size 10 15 20 40 50 100 500 1000 1500 3000 3000
Nodes n 560842 240807 172644 110324 103903 101052 100919 138706 100919 77741 69092
Triangles n 140118 70994 48044 28684 26868 26024 25948 29970 25948 23230 22232
Tetrahedrons n 313370 126061 92463 60451 57002 55513 55480 80746 55480 40067 34291
Displacement magnitude max mm 0 0 0 0 0 0 0 0 0 0 0
Displacement magnitude min mm 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2
Displacement X max um -31.59 -31.59 -31.59 -31.59 -31.56 -31.46 -31.47 -31.32 -31.47 -31.33 -30.91
Displacement X min um 1.45 1.45 1.45 1.45 1.44 1.43 1.42 1.46 1.42 1.37 1.28
Displacement Y max um -12.69 -12.69 -12.69 -12.69 -12.68 -12.67 -12.67 -12.69 -12.67 -12.64 -12.57
Displacement Y min um 16.03 16.03 16.03 16.03 16.03 16.01 16 15.98 16 16.01 16.1
Displacement Z max mm -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2
Displacement Z min um 1.8 1.8 1.8 1.8 1.8 1.81 1.81 1.81 1.81 1.77 1.71
von Mises Stress max kPa 0 0 0 0 0 0 0 0 0 0 0
von Mises Stress min kPa 1281.81 1281.81 1281.81 1281.81 1297.14 1311.81 1286.65 1250 1286.65 1273.95 1282.35
Max Principal Stress max kPa -176.22 -176.22 -176.22 -176.22 -172.74 -172.69 -171.95 -184.54 -171.95 -169.48 -180.97
Max Principal Stress min kPa 967.43 967.43 967.43 967.43 1014.52 955.45 1085.01 1140.49 1085.01 798.06 754.78
Min Principal Stress max kPa -1345.87 -1345.87 -1345.87 -1345.87 -1358.44 -1343.18 -1306.44 -1295.94 -1306.44 -1325.73 -1359.73
Min Principal Stress min kPa 109.99 109.99 109.99 109.99 108.23 114.84 115.2 126.83 115.2 106.69 119.98
Max Shear Stress max kPa 0 0 0 0 0 0 0 0 0 0 0
Max Shear Stress min kPa 648.93 648.93 648.93 648.93 658.46 663.91 654.4 628.53 654.4 647.25 647.95

Read and Interpolate

import matplotlib.pyplot as plt
import pandas  as pd
import numpy as np

#Read, transpose, sort, drop and set the index to be the number of tetrahedrons
#and drop the columns with zero values and some parameters
df = pd.read_csv("convergence_dataOnly.csv" ).T
df.columns = ( df.iloc[0] + " " + df.iloc[1] )
df = df[3:].sort_values("Tetrahedrons n")
df.set_index("Tetrahedrons n", inplace=True)
df = df.drop('Displacement magnitude max', axis=1)
df = df.drop('von Mises Stress max', axis=1)
df = df.drop('Max Shear Stress max', axis=1)
df = df.drop('Nodes n', axis=1)
df = df.drop('Triangles n', axis=1)

#Convert values and index to numeric
df= df.apply(pd.to_numeric)
df.index = pd.to_numeric( df.index, errors='coerce' )

# Interpolate # Need to drop the one with the same number of tetrahedrons
mask = np.ones( len(df), dtype=bool)
mask[2] = False
df = df[mask]

#Get the percentage
df = df.divide( df.iloc[9] )
print(df)

df_i = df.reindex(df.index.union(np.linspace(df.index.min(),df.index.max(), df.index.shape[0]*10)))  # insert 10 NaN points between existing ones
df_i = df_i.interpolate('pchip', order=2)  # fill the gaps with values
df_i.plot( legend=False)  # draw new Dataframe

Animate the data

Images to GIF

Reverse the layers: From the main menu through Layers → Stack → Reverse Layer Order.

Animate 1 line updating

Click the image to see the animation

This tutorial was found on https://docs.kanaries.net/topics/Matplotlib/matplotlib-animation.

from matplotlib.animation import FuncAnimation

x = df_i.index.to_numpy()
y = df_i["Max Shear Stress min"].to_numpy()
xdata, ydata = [], []

fig, ax = plt.subplots()
fig.set_size_inches( 10/2.54, 20/2.54  )
ax.set(xlim=(0, max(x)), ylim=(.8, 1.2))
line = ax.plot( [], [], color='r', lw=2)[0]

def animate(i):
    xdata.append( x[i] )
    ydata.append( y[i] )
    line.set_data( xdata, ydata )
    plt.savefig("image{i}.png".format(i=i), dpi=300 )
    return line

anim = FuncAnimation(fig, animate, frames=x.size, interval=100, repeat=False)
plt.show()

Animate N lines updating

Click the image to see the animation.

Animation is easy, once you find the correct tutorial.

from matplotlib.animation import FuncAnimation

x = df_i.index.to_numpy()
y = df_i.to_numpy()

fig, ax = plt.subplots()
ax.set(xlim=(0, max(x)), ylim=(.7, 1.3))
lines = ax.plot(np.empty((0, y.shape[1])), np.empty((0, y.shape[1])), lw=2)

def animate(i):
    for line_k, y_k in zip(lines, y.T):
        line_k.set_data(x[:i], y_k[:i])
    plt.savefig("image{i}.png".format(i=1), dpi=50 )
    return lines

anim = FuncAnimation(fig, animate, frames=x.size, interval=100, repeat=False)
plt.show()

Animate x + t dimensional

Brushing Up Science demonstrates many beautiful animation procedures. This is one (https://brushingupscience.com/2016/06/21/matplotlib-animations-the-easy-way/):

fig, ax = plt.subplots(figsize=(5, 3))
ax.set(xlim=(-3, 3), ylim=(-1, 1))

x = np.linspace(-3, 3, 91)
t = np.linspace(1, 25, 30)
X2, T2 = np.meshgrid(x, t)

sinT2 = np.sin(2*np.pi*T2/T2.max())
F = 0.9*sinT2*np.sinc(X2*(1 + sinT2))

line = ax.plot(x, F[0, :], color='k', lw=2)[0]

def animate(i):
    line.set_ydata(F[i, :])

anim = FuncAnimation( fig, animate, interval=100, frames=len(t)-1 )

plt.draw()
plt.show()

Animate 2

Add the new points in the update function. The clear command clears everything, so this in not very neat.

from random import randint

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

# create empty lists for the x and y data
x = []
y = []

# create the figure and axes objects
fig, ax = plt.subplots()


def animate(i):
    pt = randint(1,9) # grab a random integer to be the next y-value in the animation
    x.append(i)
    y.append(pt)
    ax.clear()
    ax.set_xlim([0,20])
    ax.set_ylim([0,10])
    ax.plot(x,y)

# run the animation
ani = FuncAnimation(fig, animate, frames=20, interval=100, repeat=False)

plt.show()

Animate 3

References