Source code for ldds.tools

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import ipywidgets as widgets

[docs]def draw_ld(fig, axis, LD, grid_parameters, subplot_title, interactive, cmap='viridis'): """ Draws a Lagrangian descriptor contour plot and a contour plot showing the magnitude of its gradient field. Parameters ---------- fig : matplotlib.figure.Figure Figure where contour plot will be drawn. axis : matplotlib.axes._subplots.AxesSubplot Axis handle of subplot in figure. LD : ndarray, shape(n, ) Array to be plotted. grid_parameters : list of 3-tuples of floats Limits and size of mesh per axis. subplot_title : string Subplot title. interactive : bool True allows interactively adjusting the gradient contouor plot minimum and maximum. cmap: string Name of matplotlib colormap for plot. """ #axes if type(grid_parameters) == dict: #n-DoF systems slice_parameters = grid_parameters['slice_parameters'] # 2n-D grid dims_slice = np.array(grid_parameters['dims_slice']) if len(dims_slice) == 2: labels = ['$x$', '$p_x$'] elif len(dims_slice) == 4: labels = np.array(['$x$','$y$','$p_x$','$p_y$']) elif len(dims_slice) == 6: labels = np.array(['$x$','$y$','$z$','$p_x$','$p_y$','$p_z$']) else: labels = np.array(['']*len(dims_slice)) slice_axes_labels = labels[dims_slice==1] else: #1-DoF systems slice_parameters = grid_parameters # 2-D grid slice_axes_labels = ['$x$', '$p_x$'] ax1_min, ax1_max, N1 = slice_parameters[0] ax2_min, ax2_max, N2 = slice_parameters[1] points_ax1 = np.linspace(ax1_min, ax1_max, N1) points_ax2 = np.linspace(ax2_min, ax2_max, N2) # plot n_levels = 100 vmin = np.nanmin(LD) vmax = np.nanmax(LD) interact_step = (vmax-vmin)/n_levels con1 = axis.contourf(points_ax1, points_ax2, LD, cmap=cmap, levels=n_levels) if interactive: @widgets.interact(clim_min=(vmin, vmax-interact_step, interact_step),clim_max=(vmin+interact_step, vmax, interact_step)) def update(clim_min=vmin,clim_max=vmax): clim_max = max(clim_min+interact_step, clim_max) con1.set_clim(clim_min,clim_max) axins = inset_axes(axis, width="5%", height="100%", loc='lower left', bbox_to_anchor=(1.025, 0., 1, 1), bbox_transform=axis.transAxes, borderpad=0 ) ticks_gradient = np.linspace(vmin,vmax, 11) fig.colorbar(con1, cax=axins, ticks=ticks_gradient, format='%.1f', orientation='vertical') axis.set_title(subplot_title) axis.set_xlabel(slice_axes_labels[0]) axis.set_ylabel(slice_axes_labels[1])
[docs]def draw_ld_pair(LD, LD_gradient, grid_parameters, plot_title, interactive, cmap_gradient): """ Lagrangian descriptor plot wrapper. Parameters ---------- LD : ndarray, shape(n, ) Array of Lagrangian Descriptor values. LD_gradient : ndarray, shape(n, ) Array of Lagrangian Descriptor gradient values. grid_parameters : list of 3-tuples of floats Limits and size of mesh per axis. plot_title : string Plot title. interactive : bool True allows interactively adjusting the gradient contouor plot minimum and maximum. cmap_gradient : string Name of matplotlib colormap for gradient contour plot. Returns ------- fig : `~.figure.Figure` ax : `.axes.Axes` or array of Axes """ fig, ax = plt.subplots(1, 2, figsize=(7.5,3), dpi=130, sharex=True, sharey=True) plt.subplots_adjust(top=0.85, bottom=0.13, wspace=0.34) #margins to accommodate boundary of interactive figure environment plt.suptitle(plot_title) draw_ld(fig, ax[0], normalise(LD), grid_parameters, 'LD values', interactive=False) draw_ld(fig, ax[1], LD_gradient, grid_parameters, 'LD gradient magnitude', interactive, cmap=cmap_gradient) return fig, ax
[docs]def normalise(A): """ Normalises an array. Parameters ---------- A : ndarray, shape(n, ) Array of input values. Returns ------- Normalised array : ndarray, shape(n, ). """ return (A - np.nanmin(A)) / (np.nanmax(A) - np.nanmin(A))
[docs]def get_gradient_magnitude(LD): """ Calculates magnitude of the gradient of input array LD. Parameters ---------- LD : ndarray, shape(n, ) Array of input values. Returns ------- gradient_magnitude : ndarray, shape(n, ) Magnitude of the gradient of input array LD. """ gradient_x, gradient_y = np.gradient(LD) gradient_magnitude = np.sqrt(gradient_x**2 + gradient_y**2) return normalise(gradient_magnitude)
[docs]def draw_all_lds(LD_forward, LD_backward, grid_parameters, tau=np.nan, p_value=np.nan, interactive=False): """ Draws the forward, backward and total Lagrangian descriptor contour plots and a contour plots showing the magnitude of its gradient field. Parameters ---------- LD_forward : ndarray, shape(n, ) Array of Lagrangian Descriptor values in forward time. LD_backward : ndarray, shape(n, ) Array of Lagrangian Descriptor values in backward time. grid_parameters : list of 3-tuples of floats Limits and size of mesh per axis. tau : float, optional Time of integration. Default is np.nan. p_value : float, optional Exponent in Lagrangian descriptor definition. Default is np.nan. interactive : bool, optional True allows interactively adjusting the gradient plot minimum and maximum. Default is False. Returns ------- List of tuples of the form (fig, ax). """ # Prepare method name if np.isnan(p_value): t_final = np.nan else: if p_value == 2: str_method = 'Arclength LD' elif p_value >= 1: str_method = r'p-norm LD$(p={'+str(p_value)+r'})$' elif p_value == 0: str_method = 'Action-based LD' elif p_value < 1: str_method = r'LD$_{'+str(p_value)+r'}$' else: str_method = '' t_final=np.abs(tau) # Plot LDs plot_handles=[] if len(LD_forward)>0: if np.isnan(t_final): plot_title='' else: plot_title = r'Forward {}, $\tau={}$'.format(str_method,t_final) LD_forward_gradient = get_gradient_magnitude(LD_forward) plot_tuple = draw_ld_pair(LD_forward, LD_forward_gradient, grid_parameters, plot_title, interactive, 'Blues') plot_handles.append(plot_tuple) if len(LD_backward)>0: if np.isnan(t_final): plot_title='' else: plot_title = r'Backward {}, $\tau={}$'.format(str_method,t_final) LD_backward_gradient = -get_gradient_magnitude(LD_backward) plot_tuple = draw_ld_pair(LD_backward, LD_backward_gradient, grid_parameters, plot_title, interactive, 'Reds_r') plot_handles.append(plot_tuple) if len(LD_forward)>0 and len(LD_backward)>0: if np.isnan(t_final): plot_title='' else: plot_title = r'Total {}, $\tau={}$'.format(str_method,t_final) plot_tuple = draw_ld_pair(LD_backward+LD_forward, LD_forward_gradient+LD_backward_gradient, grid_parameters, plot_title, interactive, 'RdBu') plot_handles.append(plot_tuple) plt.show() return plot_handles
__author__ = 'Broncio Aguilar-Sanjuan, Victor-Jose Garcia-Garrido, Vladimir Krajnak, Shibabrat Naik' __status__ = 'Development'