def plot_frames(iom, blockid=0, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, imgsize=(12,9)):
    """Plot the wave function for a series of timesteps.
    :param iom: An ``IOManager`` instance providing the simulation data.
    :param view: The aspect ratio.
    :param plotphase: Whether to plot the complex phase. (slow)
    :param plotcomponents: Whether to plot the real/imaginary parts..
    :param plotabssqr: Whether to plot the absolute value squared.
    """
    parameters = iom.load_parameters()

    grid = iom.load_grid(blockid="global")
    timegrid = iom.load_wavefunction_timegrid(blockid=blockid)

    # Precompute eigenvectors for efficiency
    Potential = PotentialFactory().create_potential(parameters)
    eigenvectors = Potential.evaluate_eigenvectors_at(grid)

    for step in timegrid:
        print(" Plotting frame of timestep # " + str(step))

        wave = iom.load_wavefunction(blockid=blockid, timestep=step)
        values = [ wave[j,...] for j in xrange(parameters["ncomponents"]) ]

        # Transform the values to the eigenbasis
        # TODO: improve this:
        if parameters["algorithm"] == "fourier":
            ve = Potential.project_to_eigen(grid, values, eigenvectors)
        else:
            ve = values

        # Plot the probability densities projected to the eigenbasis
        fig = figure(figsize=imgsize)

        for index, component in enumerate(ve):
            ax = fig.add_subplot(parameters["ncomponents"],1,index+1)
            ax.ticklabel_format(style="sci", scilimits=(0,0), axis="y")

            if plotcomponents is True:
                ax.plot(grid, real(component))
                ax.plot(grid, imag(component))
                ax.set_ylabel(r"$\Re \varphi_"+str(index)+r", \Im \varphi_"+str(index)+r"$")
            if plotabssqr is True:
                ax.plot(grid, component*conj(component))
                ax.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")
            if plotphase is True:
                plotcf(grid, angle(component), component*conj(component))
                ax.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")

            ax.set_xlabel(r"$x$")

            # Set the aspect window
            if view is not None:
                ax.set_xlim(view[:2])
                ax.set_ylim(view[2:])

        fig.suptitle(r"$\Psi$ at time $"+str(step*parameters["dt"])+r"$")
        fig.savefig("wavefunction_block"+str(blockid)+"_"+ (7-len(str(step)))*"0"+str(step) +GD.output_format)
        close(fig)

    print(" Plotting frames finished")
Example #2
0
def plot_frame(step, parameters, grid, values, coeffs, index=0, view=None, imgsize=(12,9)):
    n = parameters["ncomponents"]
    k = array(range(parameters["basis_size"]))

    # Start new plot
    fig = figure(figsize=imgsize)

    for s in xrange(n):
        y = values[s]
        c = squeeze(coeffs[s])

        # Plot the probability densities
        ax1 = fig.add_subplot(n,2,2*s+1)
        ax1.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
        plotcf(grid, angle(y), conj(y)*y)

        if view is not None:
            ax1.set_xlim(view[:2])
            ax1.set_ylim(view[2:])

        ax1.set_xlabel(r"$x$")
        ax1.set_ylabel(r"$\langle\varphi_"+str(s)+r"|\varphi_"+str(s)+r"\rangle$")

        # Plot the coefficients of the Hagedorn wavepacket
        ax2 = fig.add_subplot(n,2,2*s+2)
        ax2.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
        stemcf(k, angle(c), abs(c))

        # axis formatting:
        m = max(abs(c))
        ax2.set_xlim(-1,parameters["basis_size"])
        ax2.set_ylim(-0.1*m, 1.1*m)

        ax2.set_xlabel(r"$k$")
        ax2.set_ylabel(r"$|c|$")

    fig.suptitle(r"Time $"+str(step*parameters["dt"])+r"$")
    fig.savefig("wavepackets_block"+str(index)+"_"+ (7-len(str(step)))*"0"+str(step) +GD.output_format)
    close(fig)
def plot_frames(
    iom_s, iom_o, gid, bid_ref=0, view=None, plotphase=False, plotcomponents=False, plotabssqr=True, imgsize=(12, 9)
):
    """Plot the wave function for a series of timesteps.
    :param iom_s: An ``IOManager`` instance providing the spawning simulation data.
    :param iom_o: An ``IOManager`` instance providing the reference simulation data.
    :param view: The aspect ratio.
    :param plotphase: Whether to plot the complex phase. (slow)
    :param plotcomponents: Whether to plot the real/imaginary parts..
    :param plotabssqr: Whether to plot the absolute value squared.
    """
    parameters_o = iom_o.load_parameters()
    parameters_s = iom_s.load_parameters()

    grid_o = iom_o.load_grid(blockid="global")
    grid_s = iom_s.load_grid(blockid="global")

    timegrid_o = iom_o.load_wavefunction_timegrid(blockid=bid_ref)

    # For each mother-child spawn try pair
    bidm, bidc = iom_s.get_block_ids(groupid=gid)

    for step in timegrid_o:
        print(" Timestep # " + str(step))

        # Retrieve reference data
        wave_o = iom_o.load_wavefunction(timestep=step, blockid=bid_ref)
        values_o = [wave_o[j, ...] for j in xrange(parameters_o["ncomponents"])]

        # Retrieve spawn data for both packets
        values_s = []
        try:
            # Load data of original packet
            wave = iom_s.load_wavefunction(timestep=step, blockid=bidm)
            values.append([wave[j, ...] for j in xrange(parameters_s["ncomponents"])])

            # Load data of spawned packet
            wave = iom_s.load_wavefunction(timestep=step, blockid=bidc)
            values.append([wave[j, ...] for j in xrange(parameters_s["ncomponents"])])

            have_spawn_data = True
        except ValueError:
            have_spawn_data = False

        # Plot the probability densities projected to the eigenbasis
        fig = figure(figsize=imgsize)

        # Create a bunch of subplots
        axes = []

        for index in xrange(parameters_o["ncomponents"]):
            ax = fig.add_subplot(parameters_o["ncomponents"], 1, index + 1)
            ax.ticklabel_format(style="sci", scilimits=(0, 0), axis="y")
            axes.append(ax)

        # Plot reference Wavefunction
        for index, component in enumerate(values_o):
            # Plot the packet
            if plotcomponents is True:
                axes[index].plot(grid_o, real(component), color="blue")
                axes[index].plot(grid_o, imag(component), color="green")
                axes[index].set_ylabel(r"$\Re \varphi_" + str(index) + r", \Im \varphi_" + str(index) + r"$")
            if plotabssqr is True:
                axes[index].plot(grid_o, component * conj(component), color="black")
                axes[index].set_ylabel(r"$\langle \varphi_" + str(index) + r"| \varphi_" + str(index) + r"\rangle$")
            if plotphase is True:
                plotcf(grid_o, angle(component), component * conj(component))
                axes[index].set_ylabel(r"$\langle \varphi_" + str(index) + r"| \varphi_" + str(index) + r"\rangle$")

        # Plot spawned Wavefunctions
        if have_spawn_data is True:
            # For all spawned packets a.k.a data blocks
            for colind, values in enumerate(values_s):
                # For all components of a packet
                for index, component in enumerate(values):
                    # Plot the packet
                    if plotcomponents is True:
                        axes[index].plot(grid_s, real(component), color="cyan")
                        axes[index].plot(grid_s, imag(component), color="lightgreen")
                        axes[index].set_ylabel(r"$\Re \varphi_" + str(index) + r", \Im \varphi_" + str(index) + r"$")
                    if plotabssqr is True:
                        axes[index].plot(grid_s, component * conj(component), color=colors_mc[colind])
                        axes[index].set_ylabel(
                            r"$\langle \varphi_" + str(index) + r"| \varphi_" + str(index) + r"\rangle$"
                        )
                    if plotphase is True:
                        plotcf(grid_s, angle(component), component * conj(component))
                        axes[index].set_ylabel(
                            r"$\langle \varphi_" + str(index) + r"| \varphi_" + str(index) + r"\rangle$"
                        )

        # Set the axis properties
        for index in xrange(len(values_o)):
            axes[index].set_xlabel(r"$x$")

            # Set the aspect window
            if view is not None:
                axes[index].set_xlim(view[:2])
                axes[index].set_ylim(view[2:])

        fig.suptitle(r"$\Psi$ at time $" + str(step * parameters_o["dt"]) + r"$")
        fig.savefig(
            "wavefunction_compare_spawned_group" + str(gid) + (5 - len(str(step))) * "0" + str(step) + GD.output_format
        )
        close(fig)

    print(" Plotting frames finished")
Example #4
0
from matplotlib.pyplot import *

from WaveBlocks.Plot import plotcf

x = np.r_[0.0:2.0*np.pi:1j*2**9]
u = np.exp(1.0j*x)

rvals = np.real(u)
ivals = np.imag(u)
cvals = np.conjugate(u)*u
angles = np.angle(u)

figure(figsize=(20,20))

subplot(2,2,1)
plotcf(x, angles, rvals)
xlim([0,2*np.pi])
ylim([-1.5, 1.5])
xlabel(r"$\Re \psi$")

subplot(2,2,2)
plotcf(x, angles, ivals, color="k")
xlim([0,2*np.pi])
ylim([-1.5, 1.5])
xlabel(r"$\Im \psi$")

subplot(2,2,3)
plotcf(x, angles, cvals, darken=True)
xlim([0,2*np.pi])
ylim([0, 1.5])
xlabel(r"$|\psi|^2$")
Example #5
0
from matplotlib.pyplot import *

from WaveBlocks.ComplexMath import *
from WaveBlocks.Plot import plotcf


# Continuous complex angle function
a = linspace(0,5,1000)
b = linspace(5,10,1000)

c = hstack([a, b])
y = hstack([ exp(-1.0j*a**2), exp(+1.0j*b**1.6) ])

figure()

plotcf(c, angle(y), abs(y))
plot(c, real(y), "b-", label=r"$\Re y$")
plot(c, imag(y), "g-", label=r"$\Im y$")
plot(c, angle(y), "c-", label=r"$\arg y$")
plot(c, cont_angle(y), "m-", label=r"$\arg_c y$")
plot(c, pi*ones(c.shape), "y--", label=r"$\pi$")
plot(c, -pi*ones(c.shape), "y--", label=r"$-\pi$")

legend(loc="lower left")
savefig("complex_angle_continuous.png")


# Continuous complex sqrt
x = linspace(0, 6*pi, 5000)
y = 2*exp(1.0j*x)
y = Psi.evaluate_at(x, prefactor=True)[0]

# <codecell>

plot(x, abs(y)**2)
xlabel(r"$x$")
ylabel(r"$|\Psi|^2$")

# <codecell>

from WaveBlocks.Plot import plotcf, stemcf

# <codecell>

plotcf(x, angle(y), abs(y)**2)
xlabel(r"$x$")
ylabel(r"$|\Psi|^2$")

# <codecell>

c = Psi.get_coefficients(component=0)
c = squeeze(c)

# <codecell>

c.shape

# <codecell>

figure(figsize=(6,4))
Example #7
0
from numpy import *
from matplotlib.pyplot import *
from WaveBlocks.Plot import plotcf

a = linspace(0, 2 * pi, 6000)
y = exp(1.0j * a)

fig = figure()
ax = fig.gca()

plotcf(a, angle(y), abs(y))
ax.plot(a, real(y), "b-", label=r"$\Re y$")
ax.plot(a, imag(y), "g-", label=r"$\Im y$")
ax.plot(a, angle(y), "c-", label=r"$\arg y$")

ax.set_xlim(0, 2 * pi)

ax.set_xticks((0, pi / 4, pi / 2, 3 * pi / 4, pi, 5 * pi / 4, 3 * pi / 2, 7 * pi / 4, 2 * pi))

ax.set_xticklabels(
    (
        r"$0$",
        r"$\frac{\pi}{4}$",
        r"$\frac{\pi}{2}$",
        r"$\frac{3\pi}{4}$",
        r"$\pi$",
        r"$\frac{5\pi}{4}$",
        r"$\frac{3\pi}{2}$",
        r"$\frac{7\pi}{4}$",
        r"$2\pi$",
    )
# A HAWP
HAWP = HagedornWavepacket(params)
HAWP.set_quadrature(None)

HAWP.set_parameters((1j, 1, 0, 3, -2))
HAWP.set_coefficient(0,2,1)

# Evaluate in real space
y = HAWP.evaluate_at(x)[0]

# Transform to Fourier space
HAWP.to_fourier_space()
# Evaluate in Fourier space
w = HAWP.evaluate_at(k)[0]

HAWP.to_real_space()
# Evaluate in real space again
z = HAWP.evaluate_at(x)[0]


figure()
plotcf(x, angle(y), abs(y))

figure()
plotcf(k, angle(w), abs(w))

figure()
plotcf(x, angle(z), abs(z))

show()
def plot_frames(iom, gid=0, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, imgsize=(12,9)):
    """Plot the wave function for a series of timesteps.
    :param iom: An ``IOManager`` instance providing the simulation data.
    :param gid: The group ID of the group where the two packets are stored.
    :param view: The aspect ratio.
    :param plotphase: Whether to plot the complex phase. (slow)
    :param plotcomponents: Whether to plot the real/imaginary parts..
    :param plotabssqr: Whether to plot the absolute value squared.
    """
    parameters = iom.load_parameters()

    # Block IDs for mother and child wavepacket
    bidm, bidc = iom.get_block_ids(groupid=gid)

    grid = iom.load_grid(blockid="global")

    # Precompute eigenvectors for efficiency
    Potential = PotentialFactory().create_potential(parameters)
    eigenvectors = Potential.evaluate_eigenvectors_at(grid)

    timegrid = iom.load_wavefunction_timegrid(blockid=bidm)

    for step in timegrid:
        print(" Timestep # " + str(step))

        # Retrieve spawn data for both packets
        try:
            wave_m = iom.load_wavefunction(timestep=step, blockid=bidm)
            values_m = [ wave_m[j,...] for j in xrange(parameters["ncomponents"]) ]
            have_mother_data = True
        except ValueError:
            have_mother_data = False

        # Retrieve spawn data
        try:
            wave_s = iom.load_wavefunction(timestep=step, blockid=bidc)
            values_s = [ wave_s[j,...] for j in xrange(parameters["ncomponents"]) ]
            have_spawn_data = True
        except ValueError:
            have_spawn_data = False


        # Plot the probability densities projected to the eigenbasis
        fig = figure(figsize=imgsize)

        # Create a bunch of subplots
        axes = []

        for index, component in enumerate(values_m):
            ax = fig.add_subplot(parameters["ncomponents"],1,index+1)
            ax.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
            axes.append(ax)

        # Plot original Wavefunction
        if have_mother_data is True:
            for index, component in enumerate(values_m):
                if plotcomponents is True:
                    axes[index].plot(grid, real(component))
                    axes[index].plot(grid, imag(component))
                    axes[index].set_ylabel(r"$\Re \varphi_"+str(index)+r", \Im \varphi_"+str(index)+r"$")
                if plotabssqr is True:
                    axes[index].plot(grid, component*conj(component))
                    axes[index].set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")
                if plotphase is True:
                    plotcf(grid, angle(component), component*conj(component))
                    axes[index].set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")

        # Overlay spawned parts
        if have_spawn_data is True:
            for index, component in enumerate(values_s):
                axes[index].plot(grid, component*conj(component), "-r")
                axes[index].set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")

        # Set the axis properties
        for index in xrange(len(values_m)):
            axes[index].set_xlabel(r"$x$")

            # Set the aspect window
            if view is not None:
                axes[index].set_xlim(view[:2])
                axes[index].set_ylim(view[2:])

        fig.suptitle(r"$\Psi$ at time $"+str(step*parameters["dt"])+r"$")
        fig.savefig("wavefunction_"+ (5-len(str(step)))*"0"+str(step) +GD.output_format)
        close(fig)

    print(" Plotting frames finished")
def plot_frames_split(iom, gid=0, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, imgsize=(12,9)):
    """Plot the wave function for a series of timesteps.
    :param iom: An ``IOManager`` instance providing the simulation data.
    :param gid: The group ID of the group where the two packets are stored.
    :param view: The aspect ratio.
    :param plotphase: Whether to plot the complex phase. (slow)
    :param plotcomponents: Whether to plot the real/imaginary parts..
    :param plotabssqr: Whether to plot the absolute value squared.
    """
    parameters = iom.load_parameters()
    n = parameters["ncomponents"]

    # Block IDs for mother and child wavepacket
    bidm, bidc = iom.get_block_ids(groupid=gid)

    grid = iom.load_grid(blockid="global")

    # Precompute eigenvectors for efficiency
    Potential = PotentialFactory().create_potential(parameters)
    eigenvectors = Potential.evaluate_eigenvectors_at(grid)

    timegrid = iom.load_wavefunction_timegrid(blockid=bidm)

    for step in timegrid:
        print(" Timestep # " + str(step))

        # Split grid
        gl = grid[grid<=X0]
        gr = grid[grid>X0]

        # Retrieve spawn data for both packets and split the data as necessary
        try:
            wave_m = iom.load_wavefunction(timestep=step, blockid=bidm)
            values_m = [ wave_m[j,...] for j in xrange(parameters["ncomponents"]) ]
            yl = values_m[0][grid<=X0]
            yr = values_m[0][grid>X0]
            have_mother_data = True
        except ValueError:
            have_mother_data = False

        # Retrieve spawn data
        try:
            wave_s = iom.load_wavefunction(timestep=step, blockid=bidc)
            values_s = [ wave_s[j,...] for j in xrange(parameters["ncomponents"]) ]
            ysl = values_s[0][grid<=X0]
            ysr = values_s[0][grid>X0]
            have_spawn_data = True
        except ValueError:
            have_spawn_data = False

        # Plot the probability densities projected to the eigenbasis
        fig = figure(figsize=imgsize)

        # Plot the probability density, left to X0
        ax1 = fig.add_subplot(1,2,1)
        ax1.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
        # mother
        if have_mother_data is True:
            plotcf(gl, angle(yl), conj(yl)*yl)
        # spawned
        if have_spawn_data is True:
            plot(gl, conj(ysl)*ysl, "-r")

        if view is not None:
            ax1.set_xlim(view[0],0)
            ax1.set_ylim(view[2:4])

        ax1.set_xlabel(r"$x \le 0$")
        ax1.set_ylabel(r"$\langle\varphi |\varphi \rangle$")

        # Plot the probability density, right to X0
        ax2 = fig.add_subplot(1,2,2)
        ax2.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
        # mother
        if have_mother_data is True:
            plotcf(gr, angle(yr), conj(yr)*yr)
        # spawned
        if have_spawn_data is True:
            plot(gr, conj(ysr)*ysr, "-r")

        if view is not None:
            ax2.set_xlim(0, view[1])
            ax2.set_ylim(view[4:])

        ax2.set_xlabel(r"$x > 0$")
        ax2.set_ylabel(r"$\langle\varphi |\varphi \rangle$")

        fig.suptitle(r"Time $"+str(step*parameters["dt"])+r"$")
        fig.savefig("wavepackets_"+ (5-len(str(step)))*"0"+str(step) +GD.output_format)
        close(fig)

    print(" Plotting frames finished")
Example #11
0
@copyright: Copyright (C) 2010, 2011 R. Bourquin
@license: Modified BSD License
"""

from numpy import *
from matplotlib.pyplot import *

from WaveBlocks import HagedornWavepacket
from WaveBlocks.Plot import plotcf

nmax = 10
amp0 = 0.5

params = {}
params["eps"] = 0.2
params["basis_size"] = nmax
params["ncomponents"] = 1

HAWP = HagedornWavepacket(params)
HAWP.set_parameters((1.0j, 1.0, 0.0, -1.0, 0.0))

for i in range(0,nmax):
    HAWP.set_coefficient(0, i, amp0/ 2**i)

x = linspace(-4,4,4000)
y = HAWP.evaluate_at(x, prefactor=True, component=0)

figure()
plotcf(x, angle(y), conj(y)*y)
show()
def plot_frames_homogeneous(iom, gid=0, plotphase=False, plotcomponents=False, plotabssqr=True, view=None, imgsize=(12,9)):
    """
    :param f: An ``IOManager`` instance providing the simulation data.
    """
    parameters = iom.load_parameters()

    grid = iom.load_grid(blockid="global")
    k = array(range(parameters["basis_size"]))

    # Block IDs for mother and child wavepacket
    bidm, bidc = iom.get_block_ids(groupid=gid)

    # Precompute eigenvectors for efficiency
    Potential = PotentialFactory().create_potential(parameters)

    timegrid_m = iom.load_wavefunction_timegrid(blockid=bidm)
    timegrid_s = iom.load_wavefunction_timegrid(blockid=bidc)

    for step in timegrid_m:
        print(" Timestep # " + str(step))

        # Retrieve spawn data for both packets
        try:
            wave_m = iom.load_wavefunction(timestep=step, blockid=bidm)
            values_m = [ squeeze(wave_m[j,...]) for j in xrange(parameters["ncomponents"]) ]
            coeffs_m = squeeze(iom.load_wavepacket_coefficients(timestep=step, blockid=bidm))
            have_mother_data = True
        except ValueError:
            have_mother_data = False

        # Retrieve spawn data
        try:
            wave_s = iom.load_wavefunction(timestep=step, blockid=bidc)
            values_s = [ squeeze(wave_s[j,...]) for j in xrange(parameters["ncomponents"]) ]
            coeffs_s = squeeze(iom.load_wavepacket_coefficients(timestep=step, blockid=bidc))
            have_spawn_data = True
        except ValueError:
            have_spawn_data = False

        # Start new plot
        fig = figure(figsize=imgsize)

        ax1 = subplot2grid((2,2), (0,0), colspan=2)
        ax1.ticklabel_format(style="sci", scilimits=(0,0), axis="y")

        # Plot original Wavefunction
        if have_mother_data is True:
            for index, component in enumerate(values_m):
                if plotcomponents is True:
                    ax1.plot(grid, real(component))
                    ax1.plot(grid, imag(component))
                    ax1.set_ylabel(r"$\Re \varphi_"+str(index)+r", \Im \varphi_"+str(index)+r"$")
                if plotabssqr is True:
                    ax1.plot(grid, component*conj(component))
                    ax1.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")
                if plotphase is True:
                    plotcf(grid, angle(component), component*conj(component))
                    ax1.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")

        # Overlay spawned parts
        if have_spawn_data is True:
            for index, component in enumerate(values_s):
                if plotcomponents is True:
                    ax1.plot(grid, real(component))
                    ax1.plot(grid, imag(component))
                    ax1.set_ylabel(r"$\Re \varphi_"+str(index)+r", \Im \varphi_"+str(index)+r"$")
                if plotabssqr is True:
                    ax1.plot(grid, component*conj(component))
                    ax1.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")
                if plotphase is True:
                    plotcf(grid, angle(component), component*conj(component))
                    ax1.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$")

        ax1.set_xlim(view[0:2])
        ax1.set_ylim(view[2:4])
        ax1.set_xlabel(r"$x$")
        ax1.set_title(r"Densities of mother and spawned packets")

        # Plot coefficients for mother packet
        if have_mother_data is True:
            ax2 = subplot2grid((2,2), (1,0))
            ax2.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
            stemcf(k, angle(coeffs_m), abs(coeffs_m))
            ax2.set_xlim((-1, parameters["basis_size"]))
            ax2.set_xlabel(r"$k$")
            ax2.set_ylabel(r"$|c|$")
            ax2.set_title(r"Mother packet $| \Psi^m \rangle$")

        # Plot coefficients for spawned packet
        if have_spawn_data is True:
            ax3 = subplot2grid((2,2), (1,1))
            ax3.ticklabel_format(style="sci", scilimits=(0,0), axis="y")
            stemcf(k, angle(coeffs_s), abs(coeffs_s))
            ax3.set_xlim((-1, parameters["basis_size"]))
            ax3.set_xlabel(r"$k$")
            ax3.set_ylabel(r"$|c|$")
            ax3.set_title(r"Spawned packet $| \Psi^s \rangle$")

        fig.suptitle(r"Time $"+str(step*parameters["dt"])+r"$")
        fig.savefig("wavepackets_group"+str(gid)+"_"+ (5-len(str(step)))*"0"+str(step) +GD.output_format)
        close(fig)