Kinda finished analysis and figure for Log-HP invariance (WIP).
This commit is contained in:
@@ -1,133 +1,227 @@
|
||||
import plotstyle_plt
|
||||
import glob
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from itertools import product
|
||||
from thunderhopper.modeltools import load_data
|
||||
from color_functions import load_colors
|
||||
from plot_functions import hide_axis, letter_subplots, ylimits, ylabel, super_xlabel, plot_line
|
||||
from IPython import embed
|
||||
|
||||
def prepare_fig(nrows, ncols, width=8, height=None, rheight=2,
|
||||
left=0.01, right=0.95, bottom=0.01, top=0.95,
|
||||
wspace=0.4, hspace=0.4):
|
||||
if height is None:
|
||||
height = rheight * nrows
|
||||
fig = plt.figure(figsize=(width, height))
|
||||
grid = fig.add_gridspec(nrows=nrows, ncols=ncols, wspace=wspace, hspace=hspace,
|
||||
left=left, right=right, top=top, bottom=bottom)
|
||||
axes = np.zeros((nrows, ncols), dtype=object)
|
||||
for i, j in product(range(nrows), range(ncols)):
|
||||
axes[i, j] = fig.add_subplot(grid[i, j])
|
||||
axes[i, j].set_facecolor('none')
|
||||
return fig, axes
|
||||
def strip_zeros(num, right_digits=5):
|
||||
if isinstance(num, int):
|
||||
return num
|
||||
num = f'{num:.{right_digits}f}'
|
||||
left, right = num.split('.')
|
||||
right = right.rstrip('0')
|
||||
if right:
|
||||
return f'{left}.{right}'
|
||||
return left
|
||||
|
||||
def xlimits(ax, time, minval=None, maxval=None, pad=0.05):
|
||||
limits = [minval, maxval]
|
||||
if minval is None:
|
||||
limits[0] = time[0]
|
||||
if maxval is None:
|
||||
limits[1] = time[-1]
|
||||
if pad is not None and minval is None:
|
||||
limits[0] -= (limits[1] - limits[0]) * pad
|
||||
if pad is not None and maxval is None:
|
||||
limits[1] += (limits[1] - limits[0]) * pad
|
||||
return ax.set_xlim(limits)
|
||||
|
||||
def ylimits(ax, signal, minval=None, maxval=None, pad=0.05):
|
||||
limits = [minval, maxval]
|
||||
if minval is None:
|
||||
limits[0] = signal.min()
|
||||
if maxval is None:
|
||||
limits[1] = signal.max()
|
||||
if pad is not None and minval is None:
|
||||
limits[0] -= (limits[1] - limits[0]) * pad
|
||||
if pad is not None and maxval is None:
|
||||
limits[1] += (limits[1] - limits[0]) * pad
|
||||
return ax.set_ylim(limits)
|
||||
|
||||
def ylabel(ax, label, x=-0.23, fontsize=20):
|
||||
ax.set_ylabel(label, fontsize=fontsize, rotation=0, ha='left', va='center')
|
||||
ax.yaxis.set_label_coords(x, 0.5)
|
||||
def plot_snippets(axes, time, snippets, label, scales=None,
|
||||
ymin=None, ymax=None, **kwargs):
|
||||
ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=0.05)
|
||||
ylabel(axes[0], label, x=-0.7, rotation=0, ha='left', va='center')
|
||||
for i, (ax, snippet) in enumerate(zip(axes, snippets.T)):
|
||||
plot_line(ax, time, snippet, ymin=ymin, ymax=ymax, **kwargs)
|
||||
if scales is not None:
|
||||
ax.set_title(f'$\\alpha={strip_zeros(scales[i])}$')
|
||||
return None
|
||||
|
||||
def super_xlabel(label, fig, high_ax, low_ax, y=0.005, **kwargs):
|
||||
x = (low_ax.get_position().x0 + high_ax.get_position().x1) / 2
|
||||
fig.supxlabel(label, x=x, y=y, **kwargs)
|
||||
return None
|
||||
# GENERAL SETTINGS:
|
||||
target = 'Omocestus_rufipes'
|
||||
data_paths = glob.glob(f'../data/inv/log_hp/{target}*.npz')
|
||||
stages = ['env', 'log', 'inv']
|
||||
files = stages + ['scales', 'plot_scales', 'snr_env', 'snr_log', 'snr_inv']
|
||||
save_path = '../figures/fig_invariance_log_hp.pdf'
|
||||
|
||||
def super_ylabel(label, fig, high_ax, low_ax, x=0.005, **kwargs):
|
||||
y = (low_ax.get_position().y0 + high_ax.get_position().y1) / 2
|
||||
fig.supylabel(label, x=x, y=y, **kwargs)
|
||||
return None
|
||||
# PLOT SETTINGS:
|
||||
fig_kwargs = dict(
|
||||
figsize=(32/2.54, 16/2.54),
|
||||
)
|
||||
grid1_kwargs = dict(
|
||||
nrows=len(stages),
|
||||
ncols=None,
|
||||
wspace=0.05,
|
||||
hspace=0.3,
|
||||
left=0.1,
|
||||
right=0.985,
|
||||
bottom=0.17,
|
||||
top=0.9
|
||||
)
|
||||
grid2_kwargs = dict(
|
||||
nrows=1,
|
||||
ncols=3,
|
||||
wspace=0.35,
|
||||
hspace=0,
|
||||
left=0.1,
|
||||
right=0.985,
|
||||
bottom=0.18,
|
||||
top=0.95
|
||||
)
|
||||
colors = load_colors('../data/stage_colors.npz')
|
||||
lw_snippets = 0.25
|
||||
lw_analysis = 3
|
||||
ylabels = dict(
|
||||
env=r'$x_{\text{env}}$',
|
||||
log=r'$x_{\text{dB}}$',
|
||||
inv=r'$x_{\text{adapt}}$',
|
||||
abs='abs. SNR',#'abs. ' + r'$\text{SNR}$',
|
||||
norm='norm. SNR',#'norm. ' + r'$\text{SNR}$',
|
||||
gain='rel. SNR gain'
|
||||
)
|
||||
xloc = dict(
|
||||
abs=5,
|
||||
)
|
||||
yloc = dict(
|
||||
env=100,
|
||||
log=10,
|
||||
inv=5,
|
||||
abs=50,
|
||||
)
|
||||
letter_kwargs = dict(
|
||||
x=0.03,
|
||||
y=0.99,
|
||||
ha='left',
|
||||
va='top'
|
||||
)
|
||||
fit_kwargs = dict(
|
||||
c='darkred',
|
||||
ls='--',
|
||||
zorder=1.9
|
||||
)
|
||||
fit_lw = dict(
|
||||
abs=6,
|
||||
norm=3,
|
||||
gain=3
|
||||
)
|
||||
text_kwargs = dict(
|
||||
abs=dict(s='$\\alpha^2+1$', fontsize=16, c=fit_kwargs['c'],
|
||||
x=0.85, y=0.9, ha='right', va='center'),
|
||||
norm=dict(s='$\\alpha^2+1$', fontsize=16, c=fit_kwargs['c'],
|
||||
x=0.85, y=0.9, ha='right', va='center'),
|
||||
gain=dict(s='$\\frac{1}{\\alpha}$', fontsize=24, c=fit_kwargs['c'],
|
||||
x=0.75, y=0.8, ha='left', va='center')
|
||||
)
|
||||
calculated_floor = False
|
||||
floor_kwargs = dict(
|
||||
xmin=0,
|
||||
color=3 * (0.85,),
|
||||
zorder=0,
|
||||
lw=0
|
||||
)
|
||||
|
||||
def hide_axis(ax, side='bottom'):
|
||||
ax.spines[side].set_visible(False)
|
||||
params = {side: False, 'label' + side: False}
|
||||
ax.tick_params(axis='x' if side in ['top', 'bottom'] else 'y',
|
||||
which='both', **params)
|
||||
return None
|
||||
# EXECUTION:
|
||||
for data_path in data_paths:
|
||||
print(f'Processing {data_path}')
|
||||
|
||||
def plot_line(ax, time, signal, ymin=None, ymax=None, xmin=None, xmax=None,
|
||||
xpad=None, ypad=0.05, yloc=None, **kwargs):
|
||||
handles = ax.plot(time, signal, **kwargs)
|
||||
xlimits(ax, time, minval=xmin, maxval=xmax, pad=xpad)
|
||||
ylimits(ax, signal, minval=ymin, maxval=ymax, pad=ypad)
|
||||
ax.yaxis.set_major_locator(plt.MultipleLocator(yloc))
|
||||
return handles
|
||||
# Load invariance data:
|
||||
data, config = load_data(data_path, files)
|
||||
t_full = np.arange(data['env'].shape[0]) / config['env_rate']
|
||||
nonzero_scales = data['scales'][data['scales'] > 0]
|
||||
floor_kwargs['xmax'] = data['floor_scale'] if calculated_floor else 1
|
||||
|
||||
def plot_barcode(ax, time, binary, offset=0.5, xmin=None, xmax=None, **kwargs):
|
||||
if xmin is None:
|
||||
xmin = time[0]
|
||||
if xmax is None:
|
||||
xmax = time[-1]
|
||||
lower, upper, handles = 0, 1, []
|
||||
for i in range(binary.shape[1]):
|
||||
h = ax.fill_between(time, lower, upper, where=binary[:, i], **kwargs)
|
||||
handles.append(h)
|
||||
if i < binary.shape[1] - 1:
|
||||
lower += offset + 1
|
||||
upper += offset + 1
|
||||
xlimits(ax, time, minval=xmin, maxval=xmax)
|
||||
ax.set_ylim(0, upper)
|
||||
hide_axis(ax, 'bottom')
|
||||
hide_axis(ax, 'left')
|
||||
return handles
|
||||
# Prepare overall graph:
|
||||
fig = plt.figure(**fig_kwargs)
|
||||
super_grid = fig.add_gridspec(2, 1, wspace=0, hspace=1,
|
||||
left=0, right=1, bottom=0, top=1)
|
||||
|
||||
def indicate_zoom(fig, high_ax, low_ax, zoom_abs, **kwargs):
|
||||
y0 = low_ax.get_position().y0
|
||||
y1 = high_ax.get_position().y1
|
||||
transform = low_ax.transData + fig.transFigure.inverted()
|
||||
x0 = transform.transform((zoom_abs[0], 0))[0]
|
||||
x1 = transform.transform((zoom_abs[1], 0))[0]
|
||||
rect = plt.Rectangle((x0, y0), x1 - x0, y1 - y0,
|
||||
transform=fig.transFigure, **kwargs)
|
||||
fig.add_artist(rect)
|
||||
return None
|
||||
# Prepare snippet axes:
|
||||
subfig1 = fig.add_subfigure(super_grid[0, :])
|
||||
grid1_kwargs['ncols'] = data['plot_scales'].size
|
||||
grid1 = subfig1.add_gridspec(**grid1_kwargs)
|
||||
axes = np.zeros((grid1.nrows, grid1.ncols), dtype=object)
|
||||
for i, j in product(range(grid1.nrows), range(grid1.ncols)):
|
||||
axes[i, j] = subfig1.add_subplot(grid1[i, j])
|
||||
[hide_axis(ax, 'bottom') for ax in axes[:-1, :].flatten()]
|
||||
[hide_axis(ax, 'left') for ax in axes[:, 1:].flatten()]
|
||||
super_xlabel('time [s]', subfig1, axes[-1, 0], axes[-1, -1], y=0)
|
||||
letter_subplots(axes[:, 0], labels='abc', **letter_kwargs)
|
||||
|
||||
def assign_colors(handles, types, colors):
|
||||
for handle, type_id in zip(handles, types):
|
||||
handle.set_color(colors[str(int(type_id))])
|
||||
return None
|
||||
# Prepare analysis axes:
|
||||
subfig2 = fig.add_subfigure(super_grid[1, :])
|
||||
grid2 = subfig2.add_gridspec(**grid2_kwargs)
|
||||
symlog_kwargs = dict(linthresh=nonzero_scales.min(), linscale=0.2)
|
||||
|
||||
def reorder_traces(handles, signal, zlow=2, zhigh=2.5):
|
||||
inds = np.argsort(signal.std(axis=0))
|
||||
zorders = np.linspace(zlow, zhigh, len(inds))[::-1]
|
||||
for ind, z in zip(inds, zorders):
|
||||
handles[ind].set_zorder(z)
|
||||
return None
|
||||
ax_abs_snr = subfig2.add_subplot(grid2[:, 0])
|
||||
ax_abs_snr.set_ylabel(ylabels['abs'])
|
||||
|
||||
def choose_kernels(kern_specs, features, kern_types, per_type=2, thresh=0.01):
|
||||
mean_feat = features.mean(axis=0)
|
||||
feat_diff = np.abs(mean_feat[:, None] - mean_feat[None, :])
|
||||
feat_diff[features.max(axis=0) < thresh, :] = np.nan
|
||||
feat_diff = np.nanmean(feat_diff, axis=0)
|
||||
ax_norm_snr = subfig2.add_subplot(grid2[:, 1])
|
||||
ax_norm_snr.set_ylabel(ylabels['norm'])
|
||||
ax_norm_snr.set_xscale('symlog', **symlog_kwargs)
|
||||
ax_norm_snr.set_yscale('log')
|
||||
|
||||
ranking = np.argsort(feat_diff)
|
||||
kern_inds = []
|
||||
for type_id in kern_types:
|
||||
type_inds = np.nonzero(kern_specs[:, 0] == type_id)[0]
|
||||
rank_inds = np.nonzero(np.isin(ranking, type_inds))[0][-per_type:]
|
||||
kern_inds.extend(ranking[rank_inds])
|
||||
return np.array(kern_inds)
|
||||
ax_gain = subfig2.add_subplot(grid2[:, 2])
|
||||
ax_gain.set_ylabel(ylabels['gain'])
|
||||
ax_gain.set_xscale('symlog', **symlog_kwargs)
|
||||
ax_gain.set_yscale('log')
|
||||
super_xlabel('song scale $\\alpha$', subfig2, ax_abs_snr, ax_gain)
|
||||
letter_subplots([ax_abs_snr, ax_norm_snr, ax_gain], labels='def', **letter_kwargs)
|
||||
|
||||
def letter_subplots(axes, labels='abcd', x=0.02, y=1, ha='left', va='bottom',
|
||||
fontsize=16, fontweight='bold', **kwargs):
|
||||
for ax, label in zip(axes, labels):
|
||||
ax.text(x, y, label, transform=ax.transAxes, ha=ha, va=va,
|
||||
fontsize=fontsize, fontweight=fontweight, **kwargs)
|
||||
return None
|
||||
# Plot envelope snippets:
|
||||
plot_snippets(axes[0, :], t_full, data['env'], ylabels['env'], ymin=0,
|
||||
scales=data['plot_scales'], c=colors['env'], lw=lw_snippets)
|
||||
axes[0, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc['env']))
|
||||
|
||||
# Plot logarithmic snippets:
|
||||
plot_snippets(axes[1, :], t_full, data['log'], ylabels['log'], ymax=0,
|
||||
c=colors['log'], lw=lw_snippets)
|
||||
axes[1, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc['log']))
|
||||
|
||||
# Plot invariant snippets:
|
||||
plot_snippets(axes[2, :], t_full, data['inv'], ylabels['inv'],
|
||||
c=colors['inv'], lw=lw_snippets)
|
||||
axes[2, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc['inv']))
|
||||
|
||||
# Plot in-representation SNRs (absolute):
|
||||
ax_abs_snr.plot(data['scales'], data['snr_env'], c=colors['env'], lw=lw_analysis)
|
||||
ax_abs_snr.plot(data['scales'], data['snr_log'], c=colors['log'], lw=lw_analysis)
|
||||
ax_abs_snr.plot(data['scales'], data['snr_inv'], c=colors['inv'], lw=lw_analysis)
|
||||
ax_abs_snr.axvspan(**floor_kwargs)
|
||||
ax_abs_snr.xaxis.set_major_locator(plt.MultipleLocator(xloc['abs']))
|
||||
ax_abs_snr.yaxis.set_major_locator(plt.MultipleLocator(yloc['abs']))
|
||||
ax_abs_snr.set_ylim(0, data['snr_env'].max())
|
||||
|
||||
# Plot envelope SNR fit:
|
||||
ax_abs_snr.plot(data['scales'], data['scales'] ** 2 + 1,
|
||||
lw=fit_lw['abs'], **fit_kwargs)
|
||||
ax_abs_snr.text(transform=ax_abs_snr.transAxes, **text_kwargs['abs'])
|
||||
|
||||
# Get normalized SNRs:
|
||||
norm_snr_env = data['snr_env'] / data['snr_env'].max()
|
||||
norm_snr_log = data['snr_log'] / data['snr_log'].max()
|
||||
norm_snr_inv = data['snr_inv'] / data['snr_inv'].max()
|
||||
|
||||
# Plot in-representation SNRs (normalized):
|
||||
ax_norm_snr.plot(data['scales'], norm_snr_env, c=colors['env'], lw=lw_analysis)
|
||||
ax_norm_snr.plot(data['scales'], norm_snr_log, c=colors['log'], lw=lw_analysis)
|
||||
ax_norm_snr.plot(data['scales'], norm_snr_inv, c=colors['inv'], lw=lw_analysis)
|
||||
ax_norm_snr.axvspan(**floor_kwargs)
|
||||
ax_norm_snr.set_ylim(norm_snr_env.min(), 1)
|
||||
|
||||
# # Plot envelope SNR fit:
|
||||
# ax_norm_snr.plot(nonzero_scales, nonzero_scales / nonzero_scales.max(),
|
||||
# lw=fit_lw['norm'], **fit_kwargs)
|
||||
# ax_norm_snr.text(transform=ax_norm_snr.transAxes, **text_kwargs['norm'])
|
||||
|
||||
# Get relative SNR gain:
|
||||
gain_log = norm_snr_log / norm_snr_env
|
||||
gain_inv = norm_snr_inv / norm_snr_env
|
||||
|
||||
# Plot across-representation gain:
|
||||
ax_gain.plot(data['scales'], gain_log, c=colors['log'], lw=lw_analysis)
|
||||
ax_gain.plot(data['scales'], gain_inv, c=colors['inv'], lw=lw_analysis)
|
||||
ax_gain.axvspan(**floor_kwargs)
|
||||
ax_gain.set_ylim(1, 10)
|
||||
|
||||
# Plot amplification fit:
|
||||
ax_gain.plot(nonzero_scales, nonzero_scales.max() / nonzero_scales,
|
||||
lw=fit_lw['gain'], **fit_kwargs)
|
||||
ax_gain.text(transform=ax_gain.transAxes, **text_kwargs['gain'])
|
||||
|
||||
if save_path is not None:
|
||||
fig.savefig(save_path)
|
||||
plt.show()
|
||||
|
||||
print('Done.')
|
||||
embed()
|
||||
|
||||
@@ -9,142 +9,11 @@ from plot_functions import prepare_fig, hide_axis, letter_subplots,\
|
||||
indicate_zoom, assign_colors, reorder_traces
|
||||
from IPython import embed
|
||||
|
||||
# def prepare_fig(nrows, ncols, width=8, height=None, rheight=2,
|
||||
# left=0.01, right=0.95, bottom=0.01, top=0.95,
|
||||
# wspace=0.4, hspace=0.4):
|
||||
# if height is None:
|
||||
# height = rheight * nrows
|
||||
# fig = plt.figure(figsize=(width, height))
|
||||
# grid = fig.add_gridspec(nrows=nrows, ncols=ncols, wspace=wspace, hspace=hspace,
|
||||
# left=left, right=right, top=top, bottom=bottom)
|
||||
# axes = np.zeros((nrows, ncols), dtype=object)
|
||||
# for i, j in product(range(nrows), range(ncols)):
|
||||
# axes[i, j] = fig.add_subplot(grid[i, j])
|
||||
# axes[i, j].set_facecolor('none')
|
||||
# return fig, axes
|
||||
|
||||
# def xlimits(ax, time, minval=None, maxval=None, pad=0.05):
|
||||
# limits = [minval, maxval]
|
||||
# if minval is None:
|
||||
# limits[0] = time[0]
|
||||
# if maxval is None:
|
||||
# limits[1] = time[-1]
|
||||
# if pad is not None and minval is None:
|
||||
# limits[0] -= (limits[1] - limits[0]) * pad
|
||||
# if pad is not None and maxval is None:
|
||||
# limits[1] += (limits[1] - limits[0]) * pad
|
||||
# return ax.set_xlim(limits)
|
||||
|
||||
# def ylimits(ax, signal, minval=None, maxval=None, pad=0.05):
|
||||
# limits = [minval, maxval]
|
||||
# if minval is None:
|
||||
# limits[0] = signal.min()
|
||||
# if maxval is None:
|
||||
# limits[1] = signal.max()
|
||||
# if pad is not None and minval is None:
|
||||
# limits[0] -= (limits[1] - limits[0]) * pad
|
||||
# if pad is not None and maxval is None:
|
||||
# limits[1] += (limits[1] - limits[0]) * pad
|
||||
# return ax.set_ylim(limits)
|
||||
|
||||
# def ylabel(ax, label, x=-0.23, fontsize=20):
|
||||
# ax.set_ylabel(label, fontsize=fontsize, rotation=0, ha='left', va='center')
|
||||
# ax.yaxis.set_label_coords(x, 0.5)
|
||||
# return None
|
||||
|
||||
# def super_xlabel(label, fig, high_ax, low_ax, y=0.005, **kwargs):
|
||||
# x = (low_ax.get_position().x0 + high_ax.get_position().x1) / 2
|
||||
# fig.supxlabel(label, x=x, y=y, **kwargs)
|
||||
# return None
|
||||
|
||||
# def super_ylabel(label, fig, high_ax, low_ax, x=0.005, **kwargs):
|
||||
# y = (low_ax.get_position().y0 + high_ax.get_position().y1) / 2
|
||||
# fig.supylabel(label, x=x, y=y, **kwargs)
|
||||
# return None
|
||||
|
||||
# def hide_axis(ax, side='bottom'):
|
||||
# ax.spines[side].set_visible(False)
|
||||
# params = {side: False, 'label' + side: False}
|
||||
# ax.tick_params(axis='x' if side in ['top', 'bottom'] else 'y',
|
||||
# which='both', **params)
|
||||
# return None
|
||||
|
||||
# def plot_line(ax, time, signal, ymin=None, ymax=None, xmin=None, xmax=None,
|
||||
# xpad=None, ypad=0.05, yloc=None, **kwargs):
|
||||
# handles = ax.plot(time, signal, **kwargs)
|
||||
# xlimits(ax, time, minval=xmin, maxval=xmax, pad=xpad)
|
||||
# ylimits(ax, signal, minval=ymin, maxval=ymax, pad=ypad)
|
||||
# ax.yaxis.set_major_locator(plt.MultipleLocator(yloc))
|
||||
# return handles
|
||||
|
||||
# def plot_barcode(ax, time, binary, offset=0.5, xmin=None, xmax=None, **kwargs):
|
||||
# if xmin is None:
|
||||
# xmin = time[0]
|
||||
# if xmax is None:
|
||||
# xmax = time[-1]
|
||||
# lower, upper, handles = 0, 1, []
|
||||
# for i in range(binary.shape[1]):
|
||||
# h = ax.fill_between(time, lower, upper, where=binary[:, i], **kwargs)
|
||||
# handles.append(h)
|
||||
# if i < binary.shape[1] - 1:
|
||||
# lower += offset + 1
|
||||
# upper += offset + 1
|
||||
# xlimits(ax, time, minval=xmin, maxval=xmax)
|
||||
# ax.set_ylim(0, upper)
|
||||
# hide_axis(ax, 'bottom')
|
||||
# hide_axis(ax, 'left')
|
||||
# return handles
|
||||
|
||||
# def indicate_zoom(fig, high_ax, low_ax, zoom_abs, **kwargs):
|
||||
# y0 = low_ax.get_position().y0
|
||||
# y1 = high_ax.get_position().y1
|
||||
# transform = low_ax.transData + fig.transFigure.inverted()
|
||||
# x0 = transform.transform((zoom_abs[0], 0))[0]
|
||||
# x1 = transform.transform((zoom_abs[1], 0))[0]
|
||||
# rect = plt.Rectangle((x0, y0), x1 - x0, y1 - y0,
|
||||
# transform=fig.transFigure, **kwargs)
|
||||
# fig.add_artist(rect)
|
||||
# return None
|
||||
|
||||
# def assign_colors(handles, types, colors):
|
||||
# for handle, type_id in zip(handles, types):
|
||||
# handle.set_color(colors[str(int(type_id))])
|
||||
# return None
|
||||
|
||||
# def reorder_traces(handles, signal, zlow=2, zhigh=2.5):
|
||||
# inds = np.argsort(signal.std(axis=0))
|
||||
# zorders = np.linspace(zlow, zhigh, len(inds))[::-1]
|
||||
# for ind, z in zip(inds, zorders):
|
||||
# handles[ind].set_zorder(z)
|
||||
# return None
|
||||
|
||||
# def choose_kernels(kern_specs, features, kern_types, per_type=2, thresh=0.01):
|
||||
# mean_feat = features.mean(axis=0)
|
||||
# feat_diff = np.abs(mean_feat[:, None] - mean_feat[None, :])
|
||||
# feat_diff[features.max(axis=0) < thresh, :] = np.nan
|
||||
# feat_diff = np.nanmean(feat_diff, axis=0)
|
||||
|
||||
# ranking = np.argsort(feat_diff)
|
||||
# kern_inds = []
|
||||
# for type_id in kern_types:
|
||||
# type_inds = np.nonzero(kern_specs[:, 0] == type_id)[0]
|
||||
# rank_inds = np.nonzero(np.isin(ranking, type_inds))[0][-per_type:]
|
||||
# kern_inds.extend(ranking[rank_inds])
|
||||
# return np.array(kern_inds)
|
||||
|
||||
# def letter_subplots(axes, labels='abcd', x=0.02, y=1, ha='left', va='bottom',
|
||||
# fontsize=16, fontweight='bold', **kwargs):
|
||||
# for ax, label in zip(axes, labels):
|
||||
# ax.text(x, y, label, transform=ax.transAxes, ha=ha, va=va,
|
||||
# fontsize=fontsize, fontweight=fontweight, **kwargs)
|
||||
# return None
|
||||
|
||||
|
||||
# GENERAL SETTINGS:
|
||||
target = 'Omocestus_rufipes'
|
||||
data_paths = glob.glob(f'../data/processed/{target}*.npz')
|
||||
stages = ['filt', 'env', 'log', 'inv', 'conv', 'bi', 'feat']
|
||||
save_path = None#'../figures/'
|
||||
save_path = '../figures/'
|
||||
|
||||
# PLOT SETTINGS:
|
||||
fig_kwargs = dict(
|
||||
@@ -348,3 +217,6 @@ for data_path in data_paths:
|
||||
if save_path is not None:
|
||||
fig.savefig(f'{save_path}fig_feat_stages.pdf')
|
||||
plt.show()
|
||||
|
||||
print('Done.')
|
||||
embed()
|
||||
@@ -17,6 +17,12 @@ def prepare_fig(nrows, ncols, width=8, height=None, rheight=2, unit=1/2.54,
|
||||
axes[i, j].set_facecolor('none')
|
||||
return fig, axes
|
||||
|
||||
def hide_ticks(ax, side='bottom', ticks=True):
|
||||
axis = 'x' if side in ['top', 'bottom'] else 'y'
|
||||
params = {side: ticks, 'label' + side: False}
|
||||
ax.tick_params(axis=axis, which='both', **params)
|
||||
return None
|
||||
|
||||
def hide_axis(ax, side='bottom'):
|
||||
ax.spines[side].set_visible(False)
|
||||
params = {side: False, 'label' + side: False}
|
||||
@@ -33,7 +39,7 @@ def letter_subplots(axes, labels=None, x=0.02, y=1, ha='left', va='bottom',
|
||||
fontsize=fontsize, fontweight=fontweight, **kwargs)
|
||||
return None
|
||||
|
||||
def xlimits(ax, time, minval=None, maxval=None, pad=0.05):
|
||||
def xlimits(time, ax=None, minval=None, maxval=None, pad=0.05):
|
||||
limits = [minval, maxval]
|
||||
if minval is None:
|
||||
limits[0] = time[0]
|
||||
@@ -44,9 +50,11 @@ def xlimits(ax, time, minval=None, maxval=None, pad=0.05):
|
||||
limits[0] -= span * pad
|
||||
if pad and maxval is None:
|
||||
limits[1] += span * pad
|
||||
return ax.set_xlim(limits)
|
||||
if ax is not None:
|
||||
return ax.set_xlim(limits)
|
||||
return limits
|
||||
|
||||
def ylimits(ax, signal, minval=None, maxval=None, pad=0.05):
|
||||
def ylimits(signal, ax=None, minval=None, maxval=None, pad=0.05):
|
||||
limits = [minval, maxval]
|
||||
if minval is None:
|
||||
limits[0] = signal.min()
|
||||
@@ -57,7 +65,9 @@ def ylimits(ax, signal, minval=None, maxval=None, pad=0.05):
|
||||
limits[0] -= span * pad
|
||||
if pad and maxval is None:
|
||||
limits[1] += span * pad
|
||||
return ax.set_ylim(limits)
|
||||
if ax is not None:
|
||||
return ax.set_ylim(limits)
|
||||
return limits
|
||||
|
||||
def xlabel(ax, label, y=-0.1, fontsize=20, **kwargs):
|
||||
ax.set_xlabel(label, fontsize=fontsize, **kwargs)
|
||||
@@ -82,8 +92,8 @@ def super_ylabel(label, fig, high_ax, low_ax, x=0.005, **kwargs):
|
||||
def plot_line(ax, time, signal, ymin=None, ymax=None, xmin=None, xmax=None,
|
||||
xpad=None, ypad=0.05, yloc=None, xloc=None, **kwargs):
|
||||
handles = ax.plot(time, signal, **kwargs)
|
||||
xlimits(ax, time, minval=xmin, maxval=xmax, pad=xpad)
|
||||
ylimits(ax, signal, minval=ymin, maxval=ymax, pad=ypad)
|
||||
xlimits(time, ax=ax, minval=xmin, maxval=xmax, pad=xpad)
|
||||
ylimits(signal, ax=ax, minval=ymin, maxval=ymax, pad=ypad)
|
||||
if xloc is not None:
|
||||
ax.xaxis.set_major_locator(plt.MultipleLocator(xloc))
|
||||
if yloc is not None:
|
||||
@@ -98,7 +108,7 @@ def plot_barcode(ax, time, binary, offset=0.5, xmin=None, xmax=None, **kwargs):
|
||||
if i < binary.shape[1] - 1:
|
||||
lower += offset + 1
|
||||
upper += offset + 1
|
||||
xlimits(ax, time, minval=xmin, maxval=xmax, pad=0)
|
||||
xlimits(time, ax=ax, minval=xmin, maxval=xmax, pad=0)
|
||||
ax.set_ylim(0, upper)
|
||||
hide_axis(ax, 'bottom')
|
||||
hide_axis(ax, 'left')
|
||||
|
||||
124
python/save_inv_data_log-hp.py
Normal file
124
python/save_inv_data_log-hp.py
Normal file
@@ -0,0 +1,124 @@
|
||||
import plotstyle_plt
|
||||
import glob
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from thunderhopper.modeltools import load_data, save_data
|
||||
from thunderhopper.filetools import crop_paths
|
||||
from thunderhopper.filters import decibel, sosfilter
|
||||
from thunderhopper.model import extract_env
|
||||
from IPython import embed
|
||||
|
||||
# GENERAL SETTINGS:
|
||||
target = 'Omocestus_rufipes'
|
||||
data_paths = glob.glob(f'../data/processed/{target}*.npz')
|
||||
save_path = '../data/inv/log_hp/'
|
||||
|
||||
# ANALYSIS SETTINGS:
|
||||
scales = np.arange(0, 10.1, 0.1)
|
||||
save_scales = np.array([0, 0.5, 1, 2, 5, 10])
|
||||
floor_percents = dict(song=100, noise=99)
|
||||
single_db_ref = True
|
||||
plot_redundant = False
|
||||
|
||||
# EXECUTION:
|
||||
for data_path, name in zip(data_paths, crop_paths(data_paths)):
|
||||
print(f'Processing {name}')
|
||||
|
||||
# Load song envelope:
|
||||
data, config = load_data(data_path, files='env')
|
||||
song, rate = data['env'], config['env_rate']
|
||||
t_full = np.arange(song.shape[0]) / rate
|
||||
|
||||
# Generate noise envelope:
|
||||
rng = np.random.default_rng()
|
||||
noise = rng.normal(size=song.shape)
|
||||
noise = extract_env(noise, rate, config=config)
|
||||
|
||||
# Normalize each:
|
||||
song /= song.std()
|
||||
noise /= noise.std()
|
||||
|
||||
# Mix song component and noise component:
|
||||
scaled = song[:, None] * scales[None, :]
|
||||
mix = scaled + noise[:, None]
|
||||
|
||||
# Find noise floor (experimental):
|
||||
song_percent = np.percentile(scaled, floor_percents['song'], axis=0)
|
||||
noise_percent = np.percentile(noise, floor_percents['noise'])
|
||||
floor_scale = scales[np.nonzero(song_percent <= noise_percent)[0][-1]]
|
||||
|
||||
# Process mixture:
|
||||
mix_log = decibel(mix, axis=None if single_db_ref else 0)
|
||||
mix_inv = sosfilter(mix_log, rate, config['inv_fcut'], 'hp',
|
||||
padtype='constant', padlen=config['padlen'])
|
||||
|
||||
# Get variances per stage:
|
||||
var_env = mix.var(axis=0)
|
||||
var_log = mix_log.var(axis=0)
|
||||
var_inv = mix_inv.var(axis=0)
|
||||
|
||||
# Get SNRs against pure noise per stage:
|
||||
base_ind = np.nonzero(scales == 0)[0][0]
|
||||
snr_env = var_env / var_env[base_ind]
|
||||
snr_log = var_log / var_log[base_ind]
|
||||
snr_inv = var_inv / var_inv[base_ind]
|
||||
|
||||
if plot_redundant:
|
||||
# Normalize SNRs:
|
||||
norm_snr_env = snr_env / snr_env.max()
|
||||
norm_snr_log = snr_log / snr_log.max()
|
||||
norm_snr_inv = snr_inv / snr_inv.max()
|
||||
|
||||
# Get SNR gain against env:
|
||||
gain_log = snr_log / snr_env
|
||||
gain_inv = snr_inv / snr_env
|
||||
|
||||
# Plot results:
|
||||
fig, axes = plt.subplots(6, 1, sharex=True, layout='constrained')
|
||||
|
||||
axes[0].set_title('variance')
|
||||
axes[0].plot(scales, var_env)
|
||||
axes[0].plot(scales, var_log)
|
||||
axes[0].plot(scales, var_inv)
|
||||
|
||||
axes[1].set_title('normalized variance')
|
||||
axes[1].plot(scales, var_env / var_env.max())
|
||||
axes[1].plot(scales, var_log / var_log.max())
|
||||
axes[1].plot(scales, var_inv / var_inv.max())
|
||||
|
||||
axes[2].set_title('SNR')
|
||||
axes[2].plot(scales, snr_env)
|
||||
axes[2].plot(scales, snr_log)
|
||||
axes[2].plot(scales, snr_inv)
|
||||
|
||||
axes[3].set_title('normalized SNR')
|
||||
axes[3].plot(scales, norm_snr_env)
|
||||
axes[3].plot(scales, norm_snr_log)
|
||||
axes[3].plot(scales, norm_snr_inv)
|
||||
|
||||
axes[4].set_title('gain (absolute SNR)')
|
||||
axes[4].plot(scales, gain_log)
|
||||
axes[4].plot(scales, gain_inv)
|
||||
|
||||
axes[5].set_title('gain (normalized SNR)')
|
||||
axes[5].plot(scales, norm_snr_log / norm_snr_env)
|
||||
axes[5].plot(scales, norm_snr_inv / norm_snr_env)
|
||||
plt.show()
|
||||
|
||||
# Save analysis results:
|
||||
save_inds = np.isin(scales, save_scales)
|
||||
if save_path is not None:
|
||||
data = dict(
|
||||
scales=scales,
|
||||
plot_scales=scales[save_inds],
|
||||
floor_scale=floor_scale,
|
||||
env=mix[:, save_inds],
|
||||
log=mix_log[:, save_inds],
|
||||
inv=mix_inv[:, save_inds],
|
||||
snr_env=snr_env,
|
||||
snr_log=snr_log,
|
||||
snr_inv=snr_inv,
|
||||
)
|
||||
save_data(save_path + name, data, config, overwrite=True)
|
||||
print('Done.')
|
||||
embed()
|
||||
Reference in New Issue
Block a user