Creating animations

Two different functions are available for animating data slices: animate_slice_axis enables animation along the third (out-of-plane) direction of a slice, and animate_slice_temp enables animation of a single slice across a temperature series.

Animate along an axis using animate_slice_axis()

animate_slice_axis() requires the specification of an axis along which to animate (0=H, 1=K, 2=L, typically), and a set of axis_values which must be an iterable providing the values of the axis at each frame of the animation. It also generally good practice to specify the colorbar limits to keep them consistent across frames. This can be accomplished by passing in a dict of keyword arguments via plot_slice_kwargs, in a manner analogous to the plot_slice() function.

For example, to animate the HK scattering plane at different values of L, axis should be 2 and the L values may be specified using numpy.arange(-1.0, 1.0, 0.1), which specifies a starting value of -1.0, an ending value of 1.0, and a step size of 0.05 along L.

from nxs_analysis_tools import *
from nxs_analysis_tools.datasets import cubic

import matplotlib.pyplot as plt
import numpy as np

# Download sample data to cache and save directory as sample_dir
sample_dir = cubic()

# Load data
data = load_transform(sample_dir + '/cubic_300.nxs', print_tree=False)
# Use load_data() if loading legacy data from CHESS!

# Generate animation
animate_slice_axis(data=data, axis=2, axis_values=np.arange(-1.0, 1.0, 0.05), plot_slice_kwargs=dict(vmin=0, vmax=100000))
Downloading file 'cubic_15.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_15.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '15/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/15/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_25.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_25.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '25/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/25/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_35.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_35.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '35/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/35/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_45.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_45.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '45/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/45/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_55.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_55.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '55/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/55/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_65.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_65.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '65/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/65/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_75.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_75.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '75/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/75/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_80.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_80.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '80/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/80/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_104.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_104.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '104/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/104/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_128.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_128.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '128/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/128/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_153.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_153.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '153/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/153/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_177.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_177.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '177/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/177/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_202.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_202.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '202/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/202/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_226.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_226.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '226/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/226/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_251.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_251.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '251/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/251/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_275.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_275.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '275/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/275/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file 'cubic_300.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/cubic_300.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
Downloading file '300/transform.nxs' from 'https://raw.githubusercontent.com/stevenjgomez/dataset-cubic/main/data/300/transform.nxs' to '/home/docs/.cache/nxs_analysis_tools/cubic'.
<matplotlib.animation.FuncAnimation at 0x7533e34dffa0>
../_images/341169f3631a58e9cbd6bb54c85df2ebde4f78336c329b14280dacb65c61bae8.png

Animate across temperatures using animate_slice_temp()

Similar to animate_slice_axis(), animate_slice_temp() accepts a nxs_analysis_tools.chess.TempDependence object in place of a single dataset, and animates along the temerature axis.

In this case, a slice must be chosen using the slice_obj argument, which is analogous to indexing a nexusformat.nexus.NXdata object, though to access all values along an axis None must be used in place of :. While these arguments are converted to slice objects within the function, in order to specify a range a slice type must be passed directly. For example, to access the slice data[-0.5:0.5, :, 0.0], the corresponding slice_obj would be [slice(-0.5,0.5), None, 0.0].

The reverse_temps argument controls whether frames are animated upon cooling (False, Default) or warming (True).

# Load the temperature dependent datasets
sample = TempDependence(sample_dir)
sample.load_transforms(print_tree=False)

# Animate the slice `data[:, -0.5:0.5, 0.0]` across temperatures
animate_slice_temp(temp_dependence=sample, slice_obj=[None, slice(-0.5,0.5), 0.0], plot_slice_kwargs = dict(vmin=0, vmax=50000))
<matplotlib.animation.FuncAnimation at 0x7533df953250>
../_images/c8c4895d54443120a8ebb021acece3bbfdf2e68178bfd160a54ac72616d888f1.png

Customizing the plots

To customize these plots further, additional keyword arguments may be passed to plot_slice via the dict plot_slice_kwargs. Keyword arguments may also be passed to the matplotlib axes via ax_kwargs. See an example below. Additionally, a custom axes object may be passed via the ax argument.

# Load data
data = load_transform(sample_dir + '/cubic_15.nxs', print_tree=False)

# Generate custom figure and axes
fig,ax = plt.subplots(figsize=(5,3))

# Generate animation
animate_slice_axis(data=data, axis=2, axis_values=np.linspace(-1.0, 1.0, 45), 
    ax=ax, # The plot will draw on the specified axes
    plot_slice_kwargs = dict(vmin=1, vmax=500000, skew_angle=90, logscale=True), # These arguments are passed to `plot_slice()`
    ax_kwargs = dict(xlim=(-1,1), ylim=(-0.5,0.5)) # These arguments are passed to `ax.set()`
)
<matplotlib.animation.FuncAnimation at 0x7533e1b4e6e0>
../_images/b77d14b48d7489ce9c623f875dd23581f7f3f77251ee6081a3fd8b1a8050924a.png

Saving the animation as a GIF

Both of the above functions offer the funcitonality of saving the animation as a gif using save_gif=True. Optionally, the filename and interval (in milliseconds) can also be set (default is 500 ms).

# Load data
data = load_transform(sample_dir + '/cubic_300.nxs', print_tree=False)

# Generate animation
animate_slice_axis(data=data, axis=2, axis_values=np.linspace(-1.0, 1.0, 45), plot_slice_kwargs=dict(vmin=0, vmax=50000),
    save_gif=True, filename='img/my_animation', interval=100,
)
../_images/3241db016c58e4e6412b389db953eba9cd63ec067dcbcaf32ec94bcd75c00add.gif
<matplotlib.animation.FuncAnimation at 0x7533e1b5b790>
../_images/1b042f105ab3e1b9f4603905707775711c880e1dd7fdc3061077fe8a94395ac6.png