Source code for ollin.movement_analyzers.velocity

import numpy as np

from .base import MovementAnalyzer


[docs]class Analyzer(MovementAnalyzer): r"""Velocity analyzer. Velocity refers to change in distance per change in time at some step of individual motion. Hence if :math:`p(t_0) = (x_0, y_0)` and :math:`p(t_1) = (x_1, y_1)` are the positions of an individual at times :math:`t_0` and :math:`t_1` then the velocity at time :math:`t_1` is defined by: .. math:: d_1 = (x_1 - x_0, y_1 - y_0) vel = \frac{||d_1||}{t_1 - t_0} """ name = 'Velocities'
[docs] def analyze(self, movement): """Extract turn angles from movement data. Get the turn angles of all individuals in movement data at every time step. Will result in an array of size [num_individuals, time_steps - 2] so that:: turn_angle = results[i, k] Means that the ``i``-th individual had a turn angle of ``turn_angle`` at the ``k``-th time step. Arguments --------- movement : :py:obj:`.Movement` Movement data to analyze Returns ------- results : :py:obj:`array` Array of shape [num_individuals, time_steps - 1] containing the turn angles of all individuals at every time step. """ data = movement.data times = movement.times dtimes = (times[1:] - times[:-1])[None, :, None] directions = (data[:, 1:, :] - data[:, :-1, :]) / dtimes complex_directions = directions[:, :, 0] + 1j * directions[:, :, 1] velocities = np.abs(complex_directions) return velocities
[docs] def plot( self, ax=None, figsize=(10, 10), num_individual=0, bins=20, width=None, cmap='Reds', alpha=0.8, log=True): """Plot distribution of velocities. Arguments --------- ax : :py:obj:`matplotlib.axes.Axes`, optional Axes object in which to plot. figsize : tuple or list, optional Size of figure to create if no axes are provided. num_individual : int or tuple or list or array, optional Selection of individuals from which to draw velocity information. If num_individual='all', all information will be plotted. bins : int, optional Number of bins to use in histogram of velocity distribution. Defaults to 20. width : float, optional Width of bars in histogram. If none is given, width will be maximum possible before overlap. cmap : str, optional Colormap to use to assign colors to histogram bars. Defaults to 'Reds'. alpha : float, optional Alpha value of plot. Defaults to 0.8. log : bool, optional If true, yaxis in histogram will have logarithmic scale. """ import matplotlib.pyplot as plt from matplotlib.cm import get_cmap if ax is None: _, ax = plt.subplots(figsize=figsize) if num_individual == 'all': vdata = self.results.ravel() elif isinstance(num_individual, int): vdata = self.results[num_individual, :] else: vdata = self.results[num_individual, :].ravel() range_ = (0, vdata.max()) histogram, _ = np.histogram( vdata, bins=bins, range=range_, normed=not log) if log: histogram = np.log(histogram + 1) if width is None: width = (range_[1] - range_[0]) / bins theta = np.linspace(range_[0], range_[1], bins, endpoint=False) bars = ax.bar(theta, histogram, width=width, bottom=0) mins, maxs = histogram.min(), histogram.max() # Use custom colors and opacity cmap = get_cmap(cmap) for value, pbar in zip(histogram, bars): pbar.set_facecolor( cmap((value - mins + 0.1) / (0.1 + maxs - mins))) pbar.set_alpha(alpha) ticks = np.linspace(0, histogram.max(), 10) ax.set_yticks(ticks) ax.set_yticklabels(np.round(ticks, 2)) ax.set_title('Velocity distribution') ax.set_xlabel('Velocity (Km/Day)') if log: ax.set_ylabel('Log count') else: ax.set_ylabel('Proportion') return ax