Animating a quiver plot

Hello everyone,

My first plotly question, so, apologies if any community formatting is missing.

However, a very quick question (I think/hope). I’m trying to created an animated quiver plot to help describe chemical kinetics for undergraduate students. In essence, I am using an individual quiver to act as an individual time point in a traditional scatter plot context. I would like to animate and have each quiver appear with each frame, either accumulatively, or as a single quiver for each point.

I would love to be able to animate this. I’ve found the ability to animate scatter plots a wonderful tool in plotly and so this was my first port of call.

Thanks, Dave

Code and data (i.e. pocbook_data1.csv file stated in code) is pasted below.

import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px
import plotly.figure_factory as ff
pio.renderers.default=‘browser’

df=pd.read_csv(r"C:\Users\Dave\Documents\pocbook_data1.csv")
df2=df.iloc[::2, :]
df2[‘gT’]=np.gradient(df2[‘Time’])
df2[‘gP’]=np.gradient(df2[‘P’])

x=df2[‘Time’]*0.1
y=df2[‘P’]
u=df2[‘gT’]
v=df2[‘gP’]*30

fig = ff.create_quiver(x, y, u, v)
fig.update_layout(
title=‘Quiver Kinetics’,
xaxis_title=“time*0.1 (s)”,
yaxis_title="[P] (M)")

fig.show()

Time S P
0 1 0
1 0.951229424 0.048770576
2 0.904837418 0.095162582
3 0.860707977 0.139292023
4 0.818730754 0.181269246
5 0.778800784 0.221199216
6 0.740818222 0.259181778
7 0.704688092 0.295311908
8 0.670320065 0.329679935
9 0.637628199 0.362371801
10 0.606530715 0.393469285
11 0.576949852 0.423050148
12 0.548811652 0.451188348
13 0.522045777 0.477954223
14 0.49658529 0.50341471
15 0.47236651 0.52763349
16 0.449328905 0.550671095
17 0.427414877 0.572585123
18 0.406569606 0.593430394
19 0.38674097 0.61325903
20 0.367879391 0.632120609
21 0.349937696 0.650062304
22 0.332871025 0.667128975
23 0.316636713 0.683363287
24 0.301194155 0.698805845
25 0.286504738 0.713495262
26 0.272531737 0.727468263
27 0.259240205 0.740759795
28 0.246596907 0.753403093
29 0.234570232 0.765429768
30 0.223130096 0.776869904
31 0.21224789 0.78775211
32 0.201896413 0.798103587
33 0.192049802 0.807950198
34 0.182683419 0.817316581
35 0.173773832 0.826226168
36 0.165298768 0.834701232
37 0.15723705 0.84276295
38 0.149568509 0.850431491
39 0.142273959 0.857726041
40 0.135335165 0.864664835
41 0.128734787 0.871265213
42 0.122456317 0.877543683
43 0.116484045 0.883515955
44 0.11080304 0.88919696
45 0.105399107 0.894600893
46 0.100258733 0.899741267
47 0.095369054 0.904630946
48 0.090717843 0.909282157
49 0.086293478 0.913706522
50 0.082084897 0.917915103
51 0.078081566 0.921918434
52 0.074273476 0.925726524
53 0.070651111 0.929348889
54 0.067205417 0.932794583
55 0.063927768 0.936072232
56 0.060809969 0.939190031
57 0.057844227 0.942155773
58 0.055023132 0.944976868
59 0.052339621 0.947660379
60 0.049786984 0.950213016
61 0.04735884 0.95264116
62 0.045049123 0.954950877
63 0.04285205 0.95714795
64 0.040762128 0.959237872
65 0.038774132 0.961225868
66 0.036883096 0.963116904
67 0.035084285 0.964915715
68 0.033373202 0.966626798
69 0.031745569 0.968254431
70 0.030197319 0.969802681
71 0.028724579 0.971275421
72 0.027323663 0.972676337
73 0.02599107 0.97400893
74 0.02472347 0.97527653
75 0.023517692 0.976482308
76 0.022370719 0.977629281
77 0.021279684 0.978720316
78 0.020241861 0.979758139
79 0.019254654 0.980745346
80 0.018315593 0.981684407
81 0.017422329 0.982577671
82 0.016572632 0.983427368
83 0.015764375 0.984235625
84 0.014995537 0.985004463
85 0.014264194 0.985735806
86 0.013568521 0.986431479
87 0.012906776 0.987093224
88 0.012277305 0.987722695
89 0.011678533 0.988321467
90 0.011108963 0.988891037
91 0.010567173 0.989432827
92 0.010051806 0.989948194
93 0.009561572 0.990438428
94 0.009095248 0.990904752
95 0.008651668 0.991348332
96 0.008229721 0.991770279
97 0.007828352 0.992171648
98 0.007446558 0.992553442
99 0.007083385 0.992916615
100 0.006737924 0.993262076

Hello @davecarbery,

You can animate the quivers accumulatively,
defining an auxiliar quiver figure for each new added quiver, and transfering data from such a figure to a frame:

import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.figure_factory as ff


#df=pd.read_csv("quiver.csv", sep='\t', names =['Time', 'S', 'P'])
df=pd.read_csv(r"C:\Users\Dave\Documents\pocbook_data1.csv")

df2=df.iloc[::2, :]
df2['gT']=np.gradient(df2['Time'])
df2['gP']=np.gradient(df2['P'])

x=df2['Time']*0.1
y=df2['P']
u=df2['gT']
v=df2['gP']*30

fig = ff.create_quiver(x[:1], y[:1], u[:1], v[:1],
                       scale=0.055,
                       arrow_scale=0.3,
                       angle=15*np.pi/180, 
                       line=dict(width=1.25, color='#8f180b'))
fig.update_layout(width=900, height=450,
                  title_text='Quiver Kinetics', title_x=0.5,
                  xaxis_title="time*0.1 (s)", xaxis_range=[0, 10], xaxis_autorange=False,
                  yaxis_range=[0, 1.1], yaxis_autorange=False,
                  yaxis_title="[P] (M)",
                  
                 );


frames = []
for k in range(1,len(df)):
    figaux = ff.create_quiver(x[:k], y[:k], u[:k], v[:k], scale=0.055,
                       arrow_scale=.3,
                       angle=angle)
    frames.append(go.Frame(data=[figaux.data[0]]))

fig.update_layout(updatemenus=[dict(type='buttons',
                  showactive=False,
                  buttons=[dict(
                            label='Play',
                            method='animate',
                            args=[None, dict(frame=dict(duration=150, redraw=False),
                                             transition=dict(duration=0),
                                             fromcurrent=True,
                                             mode='immediate')])])] )
fig.update(frames=frames)
fig.show()

If you don’t like the plot appearance, you can modify these quiver parameters in fig definition:

scale=0.055,
arrow_scale=0.3,
angle=15*np.pi/180, 
line=dict(width=1.25, color='#8f180b')
1 Like

Hi @empet,

thank you for the reply, somewhere in my mind I could see where I was trying to head to, but, this is simply fantastic. Really impressed.
Cheers, Dave

1 Like