plotting animation of different dune lee angles

Viewed 46

I am writing my master thesis about water flow patterns over dunes. I am investigating the impact of dunes with different dune lee angles on flow patterns. I will measure velocity profiles above the dunes. The shape of the dunes consists of a fixed dune stoss slope (gentle upward slope), till the dune top at fixed height of 10 cm, then a fixed gentle downward slope towards the dune brinkpoint at fixed height of 9 cm and then a steeper, varying leeslope towards the dunethrough. The dunes are fixed till the brikpoint with thus a varying leeslope with angles varying from 15 till 30 degrees, the leeside ends at the dunethrough at a height of 0 cm, but the horizontal distance thus varies. I want to make an animation of the different dunes with their varying dune lee angles, I have already made subplots from all the dunes subplots dunes But I am struggling to translate these subplots into an animation. I have. tried the animation tool (FuncAnimation) from matplotlib, but failed miserably. It is my aim to show each dune 2 seconds and to have a legend added.

The code to get the subplots is:

import matplotlib.pyplot as plt
from math import *
import numpy as np
from matplotlib import pyplot as plt

fig, axs = plt.subplots(8,2, sharex= 'col', sharey ='row', gridspec_kw={'hspace': 1.05, 'wspace': 0.1})
(ax1, ax2), (ax3, ax4), (ax5, ax6) , (ax7, ax8), (ax9, ax10), (ax11, ax12), (ax13, ax14) , (ax15, ax16) = axs
fig.suptitle('measurements velocity profiles above dunes')
ax1.set_title('dune lee: 15 degrees')
ax2.set_title('dune lee: 16 degrees')
ax3.set_title('dune lee: 17 degrees')
ax4.set_title('dune lee: 18 degrees')
ax5.set_title('dune lee: 19 degrees')
ax6.set_title('dune lee: 20 degrees')
ax7.set_title('dune lee: 21 degrees')
ax8.set_title('dune lee: 22 degrees')
ax9.set_title('dune lee: 23 degrees')
ax10.set_title('dune lee: 24 degrees')
ax11.set_title('dune lee: 25 degrees')
ax12.set_title('dune lee: 26 degrees')
ax13.set_title('dune lee: 27 degrees')
ax14.set_title('dune lee: 28 degrees')
ax15.set_title('dune lee: 29 degrees')
ax16.set_title('dune lee: 30 degrees')

duneheight = 10 # fixed dunetop
dunebrinkpoint = float(0.9*duneheight) #fixed dunebrinkpoint
brinkpointgradient = float(tan(15*pi/180)) #varying lee slope, now 15 degrees 
crestgradient = float(tan(15*pi/180))/4 #fixed gentle upward stoss side lope
stossgradient = float(tan(15*pi/180))/4 #fixed gentle downward slope from dune top towards brinkpoint

ax1.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'r-',
         )
        
brinkpointgradient = float(tan(16*pi/180)) #varying lee slope, now 16 degrees

ax2.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'y-',
         )

brinkpointgradient = float(tan(17*pi/180)) #varying lee slope, now 17 degrees

ax3.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'g-',
         )

brinkpointgradient = float(tan(18*pi/180)) #varying lee slope, now 18 degrees

ax4.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:brown',
        )


brinkpointgradient = float(tan(19*pi/180)) #varying lee slope, now 19 degrees

ax5.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:orange',
        )

brinkpointgradient = float(tan(20*pi/180)) #varying lee slope, now 20 degrees

ax6.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'b-',
        )

brinkpointgradient = float(tan(21*pi/180)) #varying lee slope, now 21 degrees

ax7.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:purple',
        )

brinkpointgradient = float(tan(22*pi/180)) #varying lee slope, now 22 degrees

ax8.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:grey',
        )


brinkpointgradient = float(tan(23*pi/180)) #varying lee slope, now 23 degrees

ax9.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'r-',
        )
        
brinkpointgradient = float(tan(24*pi/180)) #varying lee slope, now 24 degrees

ax10.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'y-',
        )

brinkpointgradient = float(tan(25*pi/180)) #varying lee slope, now 25 degrees

ax11.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'g-',
        )

brinkpointgradient = float(tan(26*pi/180)) #varying lee slope, 26 degrees

ax12.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:brown',
        )

brinkpointgradient = float(tan(27*pi/180)) #varying lee slope, 27 degrees

ax13.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:orange',
        )

brinkpointgradient = float(tan(28*pi/180)) #varying lee slope, 28 degrees

ax14.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'b-',
        )

brinkpointgradient = float(tan(29*pi/180)) #varying lee slope, 29 degrees

ax15.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:purple',
        )

brinkpointgradient = float(tan(30*pi/180)) #varying lee slope, 30 degrees

ax16.plot([0, duneheight/stossgradient, duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient,duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient,
         duneheight/stossgradient+(duneheight-dunebrinkpoint)/crestgradient+dunebrinkpoint/brinkpointgradient + duneheight/stossgradient], [0, duneheight, dunebrinkpoint, 0, duneheight], 'tab:grey',
        )
plt.show()
1 Answers

OK, first off, I'm going to give you some tips on your original code. This is the kind of info I wish I had while I was writing my masters thesis on sediment transport.

Basically: don't repeat yourself with code.

If you find yourself copy/pasting things, you need to write a loop or a function, maybe both. In our case, your original code can be as short as:

import matplotlib.pyplot as plt
from math import *
import numpy as np
from matplotlib import pyplot as plt

fig, axs = plt.subplots(8, 2, sharex='col', sharey='row',
                        figsize=(10, 10),
                        gridspec_kw={'hspace': 1.05, 'wspace': 0.1})
fig.suptitle('measurements velocity profiles above dunes')

duneheight = 10 # fixed dunetop
dunebrinkpoint = float(0.9 * duneheight) 
crestgradient = float(tan(15 * pi / 180)) / 4 
stossgradient = float(tan(15 * pi / 180)) / 4 

dunelees = np.arange(15, 31)
for ax, dlee in zip(axs.flat, dunelees):
    ax.set_title(f"dune lee: {dlee} degrees")
    brinkpointgradient = float(tan(dlee*pi/180)) #varying lee slope, now 15 degrees

    x1 = duneheight / stossgradient
    x2 = x1 + (duneheight - dunebrinkpoint) / crestgradient
    x3 = x2 + dunebrinkpoint / brinkpointgradient
    x4 = x3 + x1 
    x = [0, x1, x2, x3, x4]
    y = [0, duneheight, dunebrinkpoint, 0, duneheight]
    ax.plot(x, y, linestyle='-')

Second, I notice that you have 15 hardcoded in your calcs for the Crest and Stoss gradients. I think that's right, but double check that those shouldn't vary with the lee angle as well.

Now for the animation. I built the code below by pretty directly copy/pasting directly from matplotlib's documentation. Granted, you can't write a masters thesis by copying and pasting, but you need to be able to read the docs of the tools you're using. So I recommend forming some good habits now. It'll serve you well whether you go on to get your PhD or become a practicing engineer.

The example from the docs: https://matplotlib.org/stable/gallery/animation/animate_decay.html#sphx-glr-gallery-animation-animate-decay-py

from math import tan, pi

import numpy
from matplotlib import pyplot, animation

fig, ax = pyplot.subplots(figsize=(8, 3))
fig.suptitle('measurements velocity profiles above dunes')
dune, = ax.plot([], [], lw=2, color='k')
ax.set_xlim(0, 400)
ax.set_ylim(0, 15)
xdata, ydata = [], []


def init():
    del xdata[:]
    del ydata[:]
    dune.set_data(xdata, ydata)
    return dune,

def dune_xs():
    duneheight = 10 
    dunebrinkpoint = float(0.9 * duneheight)
    crestgradient = float(tan( 15 * pi / 180)) / 4
    stossgradient = float(tan(15 * pi / 180)) / 4 

    x1 = duneheight / stossgradient
    x2 = x1 + (duneheight - dunebrinkpoint) / crestgradient
    for lee in numpy.arange(15, 31):
        brinkpointgradient = float(tan(lee* pi / 180))
        x3 = x2 + dunebrinkpoint / brinkpointgradient
        x4 = x3 + x1
        yield [0, x1, x2, x3, x4], [0, duneheight, dunebrinkpoint, 0, duneheight], lee
        
def run(data):
    # update the data
    x, y, lee = data
    dune.set_data(x, y)
    ax.set_title(f"Lee angle: {lee} degrees")
    return dune,

ani = animation.FuncAnimation(fig, run, dune_xs, interval=120, init_func=init)
fig.tight_layout()
pyplot.show()
ani.save('dunes.gif', writer='pillow', fps=30)

enter image description here

Related