"""
Visualization of data functions.
"""
import numpy as np
[docs]def partial_deriv_plot(of, wrt, check_partials_data, title=None, jac_method='J_fwd', tol=1e-10,
binary=True):
"""
Visually examine the computed and finite differenced Jacobians.
Parameters
----------
of : str
Variable whose derivatives will be computed.
wrt : str
Variable with respect to which the derivatives will be computed.
check_partials_data : dict of dicts of dicts
First key:
is the component name;
Second key:
is the (output, input) tuple of strings;
Third key:
is one of ['rel error', 'abs error', 'magnitude', 'J_fd', 'J_fwd', 'J_rev'];
For 'rel error', 'abs error', 'magnitude' the value is: A tuple containing norms for
forward - fd, adjoint - fd, forward - adjoint.
For 'J_fd', 'J_fwd', 'J_rev' the value is: A numpy array representing the computed
Jacobian for the three different methods of computation.
title : str (Optional)
Title for the plot
If None, use the values of the arguments "of" and "wrt".
jac_method : str (Optional)
Method of computating Jacobian
Is one of ['J_fwd', 'J_rev']. Optional, default is 'J_fwd'.
tol : float (Optional)
The tolerance, below which the two numbers are considered the same for
plotting purposes.
binary : bool (Optional)
If true, the plot will only show the presence of a non-zero derivative, not the value.
Otherwise, plot the value. Default is true.
Returns
-------
matplotlib.figure.Figure
The top level container for all the plot elements in the plot.
array of matplotlib.axes.Axes objects
An array of Axes objects, one for each of the three subplots created.
Raises
------
KeyError
If one of the Jacobians is not available.
"""
# Get the first item in the dict, which will be the model
model_name = list(check_partials_data)[0]
model_jacs = check_partials_data[model_name]
key = (of, wrt)
model_jac = model_jacs[key]
# get finite difference arrays
if 'J_fd' not in model_jac:
msg = 'Jacobian "{}" not found.'
raise KeyError(msg.format('J_fd'))
fd_full = model_jac['J_fd']
fd_full_flat = fd_full.flatten() # for getting max min later
if binary:
fd_binary = fd_full.copy()
fd_binary[np.nonzero(fd_binary)] = 1.0
# get computed arrays
if jac_method not in model_jac:
msg = 'Jacobian "{}" not found.'
raise KeyError(msg.format(jac_method))
computed_full = model_jac[jac_method]
computed_full_flat = computed_full.flatten() # for getting max min later
if binary:
computed_binary = computed_full.copy()
computed_binary[np.nonzero(computed_binary)] = 1.0
# get plotting scales
stacked = np.hstack((fd_full_flat, computed_full_flat))
vmin = np.amin(stacked)
vmax = np.amax(stacked)
# basics of plot
# Cannot do this sooner because of import and matplotlib
# backend issues when testing
import matplotlib.pyplot as plt
BINARY_CMP = plt.cm.gray
NON_BINARY_CMP = plt.cm.viridis
NON_BINARY_DIFF_CMP = plt.cm.RdBu
fig, ax = plt.subplots(ncols=3, figsize=(12, 6))
if title is None:
title = str(key)
plt.suptitle(title)
# plot Jacobians
if binary:
ax[0].imshow(fd_binary.real, interpolation='none',
cmap=BINARY_CMP, aspect='auto')
im_computed = ax[1].imshow(computed_binary.real, interpolation='none', cmap=BINARY_CMP,
aspect='auto')
else:
ax[0].imshow(fd_full.real, interpolation='none', vmin=vmin, vmax=vmax, cmap=NON_BINARY_CMP,
aspect='auto')
im_computed = ax[1].imshow(computed_full.real, interpolation='none', vmin=vmin, vmax=vmax,
cmap=NON_BINARY_CMP, aspect='auto')
ax[0].set_title('Approximated Jacobian')
ax[1].set_title('User-Defined Jacobian')
# Legend
fig.colorbar(im_computed, orientation='horizontal',
ax=ax[0:2].ravel().tolist())
# plot difference between computed and finite differenced
diff = computed_full.real - fd_full.real
diff_flat = diff.flatten()
vmin = np.amin(diff_flat)
vmax = np.amax(diff_flat)
if vmax - vmin < tol: # Do not want range to be too small
vmin = -1 * tol
vmax = tol
color_limit = max(abs(vmin), abs(vmax))
im_diff = ax[2].imshow(diff, interpolation='none', vmin=-color_limit, vmax=color_limit,
cmap=NON_BINARY_DIFF_CMP, aspect='auto')
fig.colorbar(im_diff, orientation='horizontal', ax=ax[2], aspect=10)
ax[2].set_title('Difference')
plt.show()
return fig, ax