Source code for tonic.utils

from typing import Tuple

import numpy as np

import tonic.transforms as transforms


[docs]def plot_event_grid( events: np.ndarray, axis_array: Tuple[int, int] = (1, 3), plot_frame_number: bool = False, ): """Plot events accumulated as frames equal to the product of axes for visual inspection. Parameters: events: Structured numpy array of shape [num_events, num_event_channels]. axis_array: dimensions of plotting grid. The larger the grid, the more fine-grained the events will be sliced in time. plot_frame_number: optional index of frame when plotting Example: >>> import tonic >>> dataset = tonic.datasets.NMNIST(save_to='./data') >>> events, target = dataset[100] >>> tonic.utils.plot_event_grid(events) Returns: None """ try: import matplotlib.pyplot as plt except ImportError: raise ImportError( "Please install the matplotlib package to plot events. This is an optional" " dependency." ) if "y" in events.dtype.names: sensor_size_x = int(events["x"].max() + 1) sensor_size_y = int(events["y"].max() + 1) sensor_size_p = len(np.unique(events["p"])) sensor_size = (sensor_size_x, sensor_size_y, sensor_size_p) transform = transforms.ToFrame( sensor_size=sensor_size, n_time_bins=np.product(axis_array) ) frames = transform(events) fig, axes_array = plt.subplots(*axis_array) if 1 in axis_array: axes_array = axes_array.reshape(1, -1) for i in range(axis_array[0]): for j in range(axis_array[1]): frame = frames[i * axis_array[1] + j] axes_array[i, j].imshow(frame[1] - frame[0]) axes_array[i, j].axis("off") if plot_frame_number: axes_array[i, j].title.set_text(str(i * axis_array[1] + j)) plt.tight_layout() plt.show() else: sensor_size_x = int(events["x"].max() + 1) frame_transform = transforms.ToFrame( sensor_size=(sensor_size_x, 1, 1), n_time_bins=sensor_size_x * 2 ) frames = frame_transform(events) plt.imshow(frames.squeeze().T) plt.xlabel("Time") plt.ylabel("Channels")
[docs]def plot_animation(frames: np.ndarray, figsize: Tuple[int, int] = (5, 5)): """Helper function that animates a tensor of frames of shape (TCHW). If you run this in a Jupyter notebook, you can display the animation inline like shown in the example below. Parameters: frames: numpy array or tensor of shape (TCHW) Example: >>> import tonic >>> nmnist = tonic.datasets.NMNIST(save_to='./data', train=False) >>> events, label = nmnist[0] >>> >>> transform = tonic.transforms.ToFrame( >>> sensor_size=nmnist.sensor_size, >>> time_window=10000, >>> ) >>> >>> frames = transform(events) >>> animation = tonic.utils.plot_animation(frames) >>> >>> # Display the animation inline in a Jupyter notebook >>> from IPython.display import HTML >>> HTML(animation.to_jshtml()) Returns: The animation object. Store this in a variable to keep it from being garbage collected until displayed. """ try: import matplotlib.pyplot as plt from matplotlib import animation except ImportError: raise ImportError( "Please install the matplotlib package to plot events. This is an optional" " dependency." ) fig = plt.figure(figsize=figsize) if frames.shape[1] == 2: rgb = np.zeros((frames.shape[0], 3, *frames.shape[2:])) rgb[:, 1:, ...] = frames frames = rgb if frames.shape[1] in [1, 2, 3]: frames = np.moveaxis(frames, 1, 3) ax = plt.imshow(frames[0]) plt.axis("off") def animate(frame): ax.set_data(frame) return ax anim = animation.FuncAnimation(fig, animate, frames=frames, interval=100) plt.show() return anim