diff --git a/figures/fig_feat_stages.pdf b/figures/fig_feat_stages.pdf index fc13abc..84974dc 100644 Binary files a/figures/fig_feat_stages.pdf and b/figures/fig_feat_stages.pdf differ diff --git a/figures/fig_features_cross_species.pdf b/figures/fig_features_cross_species.pdf index c17d8b3..d238127 100644 Binary files a/figures/fig_features_cross_species.pdf and b/figures/fig_features_cross_species.pdf differ diff --git a/figures/fig_invariance_cross_species_thresh_appendix.pdf b/figures/fig_invariance_cross_species_thresh_appendix.pdf new file mode 100644 index 0000000..f1aad43 Binary files /dev/null and b/figures/fig_invariance_cross_species_thresh_appendix.pdf differ diff --git a/figures/fig_invariance_full_Omocestus_rufipes.pdf b/figures/fig_invariance_full_Omocestus_rufipes.pdf index 92c7cc3..a3dd958 100644 Binary files a/figures/fig_invariance_full_Omocestus_rufipes.pdf and b/figures/fig_invariance_full_Omocestus_rufipes.pdf differ diff --git a/figures/fig_invariance_short_Omocestus_rufipes.pdf b/figures/fig_invariance_short_Omocestus_rufipes.pdf index 612818f..ffee981 100644 Binary files a/figures/fig_invariance_short_Omocestus_rufipes.pdf and b/figures/fig_invariance_short_Omocestus_rufipes.pdf differ diff --git a/figures/fig_pre_stages.pdf b/figures/fig_pre_stages.pdf index 5c6e996..2057cd2 100644 Binary files a/figures/fig_pre_stages.pdf and b/figures/fig_pre_stages.pdf differ diff --git a/main.aux b/main.aux index 1290e6c..859be0e 100644 --- a/main.aux +++ b/main.aux @@ -294,6 +294,8 @@ \newlabel{}{{20}{28}{}{}{}} \@writefile{lof}{\contentsline {figure}{\numberline {21}{\ignorespaces \textbf {} }}{28}{}\protected@file@percent } \newlabel{}{{21}{28}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {22}{\ignorespaces \textbf {} }}{29}{}\protected@file@percent } +\newlabel{}{{22}{29}{}{}{}} \gdef\svg@ink@ver@settings{{\m@ne }{inkscape}{\m@ne }} \abx@aux@read@bbl@mdfivesum{1380DC8C93D2855FDB132CC5A40AD52F} -\gdef \@abspage@last{28} +\gdef \@abspage@last{29} diff --git a/main.fdb_latexmk b/main.fdb_latexmk index 4c90ea1..43c61d3 100644 --- a/main.fdb_latexmk +++ b/main.fdb_latexmk @@ -1,14 +1,14 @@ # Fdb version 4 -["biber main"] 1777306108.0762 "main.bcf" "main.bbl" "main" 1777557720.19398 0 +["biber main"] 1777306108.0762 "main.bcf" "main.bbl" "main" 1777567481.8645 0 "cite.bib" 1770904753.08918 27483 4290db0c91f7b5055e25472ef913f6b4 "" - "main.bcf" 1777557720.11922 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" + "main.bcf" 1777567481.78663 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" (generated) "main.bbl" "main.blg" (rewritten before read) -["pdflatex"] 1777557719.11318 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1777557720.1942 0 +["pdflatex"] 1777567480.79243 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1777567481.86472 0 "/etc/texmf/web2c/texmf.cnf" 1761560044.43676 475 c0e671620eb5563b2130f56340a5fde8 "" - "/home/hartling/phd/paper/paper_2025/main.tex" 1777554882.92499 53144 07c2f08efb91bd2468ab34aa57c132d9 "" + "/home/hartling/phd/paper/paper_2025/main.tex" 1777567479.54365 53364 8ab5e99e5257328c6078e2b9baba5f64 "" "/usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map" 1577235249 3524 cb3e574dea2d1052e39280babc910dc8 "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1246382020 1004 54797486969f23fa377b128694d548df "" "/usr/share/texlive/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm" 1246382020 988 bdf658c3bfc2d96d3c8b02cfc1c94c20 "" @@ -154,6 +154,7 @@ "figures/fig_auditory_pathway.pdf" 1771593904.14638 1153923 3df8539421fd21dc866cc8d320bd9b1d "" "figures/fig_feat_stages.pdf" 1777396808.63328 11308461 5755987275789763533a5fc1d513c564 "" "figures/fig_features_cross_species.pdf" 1777557683.48317 149656 7eb632892caa5fdc27f0f3f81b5c2cad "" + "figures/fig_invariance_cross_species_thresh_appendix.pdf" 1777567419.99828 302489 79d589b889cf2431f08cacd7e7578a78 "" "figures/fig_invariance_field.pdf" 1776952657.04263 9131898 e9d9acff1d03fdf60ddc9e32b87ae6c2 "" "figures/fig_invariance_full_Omocestus_rufipes.pdf" 1777482172.74892 4818225 5f2fe96d50e95be5f3f2bc7369741c1f "" "figures/fig_invariance_log-hp_appendix.pdf" 1777378237.41292 537850 039c3b97fa1196f939cb46c7124692c2 "" @@ -172,10 +173,10 @@ "figures/fig_noise_env_sd_conversion_appendix.pdf" 1776328774.43347 45466 c2be20312c1572203bdbeb9c8e32525e "" "figures/fig_pre_stages.pdf" 1777396806.3563 441645 564c887858565a15dfbfa3487e8021e4 "" "figures/fig_saturation_log-hp_appendix.pdf" 1777378621.26288 28579 137855d03bab8dc5f6d31b70d404e082 "" - "main.aux" 1777557720.11222 18884 222c10edd4cc01d3fc0fb20a437c4ed8 "pdflatex" + "main.aux" 1777567481.77963 19029 0f676d5b3491a197c377574ebead2ef5 "pdflatex" "main.bbl" 1777306108.74822 91039 1380dc8c93d2855fdb132cc5a40ad52f "biber main" - "main.run.xml" 1777557720.11922 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" - "main.tex" 1777554882.92499 53144 07c2f08efb91bd2468ab34aa57c132d9 "" + "main.run.xml" 1777567481.78763 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" + "main.tex" 1777567479.54365 53364 8ab5e99e5257328c6078e2b9baba5f64 "" (generated) "main.aux" "main.bcf" diff --git a/main.fls b/main.fls index 7e438db..80074b2 100644 --- a/main.fls +++ b/main.fls @@ -378,6 +378,11 @@ INPUT ./figures/fig_kernel_sd_perc_field_appendix.pdf INPUT ./figures/fig_kernel_sd_perc_field_appendix.pdf INPUT ./figures/fig_kernel_sd_perc_field_appendix.pdf INPUT ./figures/fig_kernel_sd_perc_field_appendix.pdf +INPUT ./figures/fig_invariance_cross_species_thresh_appendix.pdf +INPUT ./figures/fig_invariance_cross_species_thresh_appendix.pdf +INPUT ./figures/fig_invariance_cross_species_thresh_appendix.pdf +INPUT ./figures/fig_invariance_cross_species_thresh_appendix.pdf +INPUT ./figures/fig_invariance_cross_species_thresh_appendix.pdf INPUT main.aux INPUT main.run.xml OUTPUT main.run.xml diff --git a/main.log b/main.log index db73c64..ee4f7fd 100644 --- a/main.log +++ b/main.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2025.10.28) 30 APR 2026 16:01 +This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2025.10.28) 30 APR 2026 18:44 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -619,6 +619,9 @@ LaTeX Warning: Label `' multiply defined. LaTeX Warning: Label `' multiply defined. +LaTeX Warning: Label `' multiply defined. + + LaTeX Warning: Label `' multiply defined. ) @@ -901,7 +904,12 @@ File: figures/fig_kernel_sd_perc_field_appendix.pdf Graphic file (type pdf) Package pdftex.def Info: figures/fig_kernel_sd_perc_field_appendix.pdf used on input line 1017. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [28 <./figures/fig_kernel_sd_perc_short_appendix.pdf> <./figures/fig_kernel_sd_perc_field_appendix.pdf>] (./main.aux) + +File: figures/fig_invariance_cross_species_thresh_appendix.pdf Graphic file (type pdf) + +Package pdftex.def Info: figures/fig_invariance_cross_species_thresh_appendix.pdf used on input line 1027. +(pdftex.def) Requested size: 483.69687pt x 483.69566pt. + [28 <./figures/fig_kernel_sd_perc_short_appendix.pdf> <./figures/fig_kernel_sd_perc_field_appendix.pdf>] [29 <./figures/fig_invariance_cross_species_thresh_appendix.pdf>] (./main.aux) *********** LaTeX2e <2023-11-01> patch level 1 L3 programming layer <2024-01-22> @@ -915,18 +923,18 @@ Package logreq Info: Writing requests to 'main.run.xml'. ) Here is how much of TeX's memory you used: - 20857 strings out of 474222 - 453153 string characters out of 5748732 + 20864 strings out of 474222 + 453617 string characters out of 5748732 1938975 words of memory out of 5000000 - 42847 multiletter control sequences out of 15000+600000 + 42854 multiletter control sequences out of 15000+600000 569394 words of font info for 79 fonts, out of 8000000 for 9000 1143 hyphenation exceptions out of 8191 94i,18n,93p,1499b,1740s stack positions out of 10000i,1000n,20000p,200000b,200000s -Output written on main.pdf (28 pages, 38895611 bytes). +Output written on main.pdf (29 pages, 39188937 bytes). PDF statistics: - 2479 PDF objects out of 2487 (max. 8388607) - 1101 compressed objects within 12 object streams + 2547 PDF objects out of 2984 (max. 8388607) + 1124 compressed objects within 12 object streams 0 named destinations out of 1000 (max. 500000) - 118 words of extra memory for PDF output out of 10000 (max. 10000000) + 123 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/main.pdf b/main.pdf index 9b4ee74..d7876c1 100644 Binary files a/main.pdf and b/main.pdf differ diff --git a/main.synctex.gz b/main.synctex.gz index 1a5b030..c56d9b2 100644 Binary files a/main.synctex.gz and b/main.synctex.gz differ diff --git a/main.tex b/main.tex index eeebaca..dbfe102 100644 --- a/main.tex +++ b/main.tex @@ -1021,4 +1021,14 @@ initiation of one behavior over another is categorical (e.g. approach/stay) \end{figure} \FloatBarrier + +\begin{figure}[!ht] + \centering + \includegraphics[width=\textwidth]{figures/fig_invariance_cross_species_thresh_appendix.pdf} + \caption{\textbf{} + } + \label{} +\end{figure} +\FloatBarrier + \end{document} \ No newline at end of file diff --git a/python/fig_features_cross_species.py b/python/fig_features_cross_species.py index 1fb6405..ae43c0d 100644 --- a/python/fig_features_cross_species.py +++ b/python/fig_features_cross_species.py @@ -54,9 +54,9 @@ calculate_regression = True test_regression = True # SUBSET SETTINGS: -types = np.array([1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10]) +types = np.array([1, -1, 2, -2, 3, -3, 4, -4]) # types = [1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10] -sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016, 0.032]) +sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016]) # sigmas = [0.001, 0.002, 0.004, 0.008, 0.016, 0.032] kernels = None reduce_kernels = any(var is not None for var in [kernels, types, sigmas]) @@ -84,7 +84,7 @@ song_grid_kwargs = dict( ) # PLOT SETTINGS: -kern_colors = load_colors('../data/feat_colors_all.npz') +kern_colors = load_colors('../data/feat_colors_subset.npz') fs = dict( lab_norm=16, lab_tex=20, @@ -178,16 +178,44 @@ if test_regression: test_ax_side, test_ax_side ] - xlab_test = '$\\rho$' - ylab_test = '$\\text{PDF}_{\\rho}$' - xloc_test = 0.5 - yloc_test = 10 + ylab_test = '$\\rho$' + yloc_test = 0.5 ylab_test_kwargs = dict( x=-0.3, fontsize=fs['lab_norm'], ha='center', va='bottom', ) + boxplot_kwargs = dict( + positions=[0, 1], + widths=0.9, + tick_labels=['inter', 'intra'], + zorder=1, + medianprops=dict( + color='k', + lw=1, + ), + boxprops=dict( + color='k', + lw=1, + ), + ) + boxplot_kwargs.update( + capprops=boxplot_kwargs['boxprops'], + whiskerprops=boxplot_kwargs['boxprops'], + ) + boxplot_dot_kwargs = dict( + ls='none', + marker='o', + ms=4, + mec='k', + mfc='w', + mew=1.5, + alpha=0.5, + zorder=2, + ) + + nbins = 10 spec_color = 'darkorchid' song_color = 'goldenrod' @@ -385,35 +413,22 @@ for x, y in product(range(n_song), range(n_song)): if test_regression: # Add test result subplot: test_ax = fig.add_subplot(test_ax_bounds) - test_ax.xaxis.set_major_locator(plt.MultipleLocator(xloc_test)) + test_ax.set_xlim(-0.6, 1.6) + test_ax.set_ylim(0, 1) test_ax.yaxis.set_major_locator(plt.MultipleLocator(yloc_test)) - xlabel(test_ax, xlab_test, transform=fig.transFigure, **xlab_low_kwargs) ylabel(test_ax, ylab_test, **ylab_test_kwargs) + + # Show boxplots of correlation coefficients: + test_ax.boxplot([spec_regs, song_regs], **boxplot_kwargs) + + # Show underlying datapoints: + test_ax.plot(np.zeros(len(spec_regs)), spec_regs, **boxplot_dot_kwargs) + test_ax.plot(np.ones(len(song_regs)), song_regs, **boxplot_dot_kwargs) + # Perform t-test: test = ttest_ind(spec_regs, song_regs, equal_var=False) t, p = test.pvalue, test.statistic print(f'\nT-test result: t={t}, p={p}') - # Calculate histograms: - limits = np.array([min(spec_regs + song_regs), max(spec_regs + song_regs)]) - limits += np.array([-1.1, 1.1]) * (limits[1] - limits[0]) - edges = np.linspace(*limits, nbins + 1) - centers = edges[:-1] + (edges[1] - edges[0]) / 2 - spec_hist, _ = np.histogram(spec_regs, bins=edges, density=True) - song_hist, _ = np.histogram(song_regs, bins=edges, density=True) - # Plot histograms: - bar_kwargs['width'] *= (centers[1] - centers[0]) - test_ax.bar(centers, spec_hist, color=spec_color, label='inter-species', **bar_kwargs) - test_ax.bar(centers, song_hist, color=song_color, label='intra-species', **bar_kwargs) - # Indicate means: - test_ax.axvline(np.mean(spec_regs), color=spec_color, **mean_kwargs) - test_ax.axvline(np.mean(song_regs), color=song_color, **mean_kwargs) - # Add legend: - test_ax.legend(**leg_kwargs) - # Posthocs: - test_ax.set_ylim(0, max(spec_hist.max(), song_hist.max()) * 1.05) - test_ax.set_xlim(min(0, max(-1, limits[0])), - min(1, limits[1])) - if save_path is not None: fig.savefig(save_path) diff --git a/python/fig_inv_cross_spec-thresh_appendix.py b/python/fig_inv_cross_spec-thresh_appendix.py new file mode 100644 index 0000000..7feb15d --- /dev/null +++ b/python/fig_inv_cross_spec-thresh_appendix.py @@ -0,0 +1,247 @@ +import plotstyle_plt +import numpy as np +import matplotlib.pyplot as plt +from thunderhopper.modeltools import load_data +from thunderhopper.filetools import search_files +from thunderhopper.filtertools import find_kern_specs +from misc_functions import shorten_species, x_dist, y_dist, get_saturation +from color_functions import load_colors +from plot_functions import reorder_by_sd, ylabel, super_xlabel, super_ylabel,\ + title_subplot, assign_colors, strip_zeros, hide_axis,\ + hide_ticks +from IPython import embed + +# GENERAL SETTINGS: +target_species = [ + # 'Chorthippus_biguttulus', + # 'Chorthippus_mollis', + # 'Chrysochraon_dispar', + # 'Euchorthippus_declivus', + 'Gomphocerippus_rufus', + 'Omocestus_rufipes', + 'Pseudochorthippus_parallelus', +] +example_files = { + 'Chorthippus_biguttulus': 'Chorthippus_biguttulus_GBC_94-17s73.1ms-19s977ms', + 'Chorthippus_mollis': 'Chorthippus_mollis_DJN_41_T28C-46s4.58ms-1m15s697ms', + 'Chrysochraon_dispar': 'Chrysochraon_dispar_DJN_26_T28C_DT-32s134ms-34s432ms', + 'Euchorthippus_declivus': 'Euchorthippus_declivus_FTN_79-2s167ms-2s563ms', + 'Gomphocerippus_rufus': 'Gomphocerippus_rufus_FTN_91-3-884ms-10s427ms', + 'Omocestus_rufipes': 'Omocestus_rufipes_DJN_32-40s724ms-48s779ms', + 'Pseudochorthippus_parallelus': 'Pseudochorthippus_parallelus_GBC_88-6s678ms-9s32.3ms' +} +search_path = '../data/inv/full/' +save_path = '../figures/fig_invariance_cross_species_thresh_appendix.pdf' + +# ANALYSIS SETTINGS: +exclude_zero = True +thresh_rel = np.array([0, 0.5, 1, 1.5, 2, 2.5, 3]) + +# SUBSET SETTINGS: +types = np.array([1, -1, 2, -2, 3, -3, 4, -4]) +# types = [1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10] +sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016]) +# sigmas = [0.001, 0.002, 0.004, 0.008, 0.016, 0.032] +kernels = None +reduce_kernels = any(var is not None for var in [kernels, types, sigmas]) + +# GRAPH SETTINGS: +fig_kwargs = dict( + figsize=(32/2.54, 32/2.54), + nrows=thresh_rel.size, + ncols=len(target_species), + sharex=True, + sharey=True, + gridspec_kw=dict( + wspace=0.2, + hspace=0.75, + left=0.1, + right=0.95, + bottom=0.08, + top=0.98, + ) +) +inset_x_bounds = [0, -0.5, 1, 0.4] +inset_y_bounds = [1.01, 0, 0.1, 1] + +# PLOT SETTINGS: +fs = dict( + lab_norm=16, + lab_tex=20, + letter=22, + tit_norm=16, + tit_tex=20, + bar=16, +) +lw = dict( + swarm=1, + single=3, + dist=2, +) +base_color = load_colors('../data/stage_colors.npz')['feat'] +kern_colors = load_colors('../data/feat_colors_subset.npz') +median_kwargs = dict( + c='k', + lw=lw['single'], + ls='--', + zorder=3 +) +xlab = 'scale $\\alpha$' +xlab_kwargs = dict( + y=0, + fontsize=fs['lab_norm'], + ha='center', + va='bottom' +) +ylab = '$\\mu_{f_i}$' +ylab_super_kwargs = dict( + x=0, + fontsize=fs['lab_norm'], + ha='left', + va='center' +) +ylab_ax_kwargs = dict( + x=0.03, + fontsize=fs['lab_norm'], + ha='center', + va='top' +) +yloc = 0.5 +title_kwargs = dict( + x=0.5, + yref=1, + fontsize=fs['tit_norm'], + ha='center', + va='top', + fontstyle='italic' +) +plateau_settings = dict( + low=0.05, + high=0.95, + first=True, + last=True, + condense=None, +) +plateau_dot_kwargs = dict( + marker='o', + mfc=base_color, + mec='k', + ms=8, + mew=1, + clip_on=False, + zorder=6 +) +x_dist_kwargs = dict( + line_kwargs = dict( + c=base_color, + lw=lw['dist'], + ), + fill_kwargs = dict( + color=base_color, + alpha=1, + ), + nbins=100, + log=True, +) +y_dist_kwargs = dict( + line_kwargs = dict( + c=base_color, + lw=lw['dist'], + ), + fill_kwargs = dict( + color=base_color, + alpha=1, + ), + edges=np.linspace(0, 1, 101), + log=False, +) + +# EXECUTION: + +# Prepare graph: +fig, axes = plt.subplots(**fig_kwargs) +axes[0, 0].set_ylim(0, 1) +axes[0, 0].yaxis.set_major_locator(plt.MultipleLocator(yloc)) +super_xlabel(xlab, fig, axes[-1, 0], axes[-1, -1], **xlab_kwargs) +super_ylabel(ylab, fig, axes[0, 0], axes[-1, 0], **ylab_super_kwargs) +for ax, species in zip(axes[0, :], target_species): + title_subplot(ax, shorten_species(species), ref=fig, **title_kwargs) +for ax, thresh in zip(axes[:, 0], thresh_rel): + title = f'$\\Theta_i\\,=\\,{strip_zeros(thresh)}\\,\\cdot\\,\\sigma_{{\\eta_i}}$' + ylabel(ax, title, transform=fig.transFigure, **ylab_ax_kwargs) +for ax in axes[-1, :]: + hide_ticks(ax, 'bottom') + +# Run through species: +for i, species in enumerate(target_species): + print(f'Processing {species}...') + + # Load invariance data: + path = search_files(example_files[species], dir=search_path)[0] + data, config = load_data(path, ['scales', 'measure_feat', 'thresh_rel']) + scales, measure = data['scales'], data['measure_feat'] + + # Reduce data: + if exclude_zero: + inds = np.nonzero(scales > 0)[0] + scales, measure = scales[inds], measure[inds, ...] + if reduce_kernels: + kern_inds = find_kern_specs(config['k_specs'], kernels, types, sigmas) + measure = measure[:, kern_inds, :] + config['kernels'] = config['kernels'][:, kern_inds] + config['k_specs'] = config['k_specs'][kern_inds, :] + if i == 0: + # Update settings: + x_dist_kwargs['edges'] = np.geomspace(scales[scales > 0][0], scales[-1], + x_dist_kwargs['nbins'] + 1) + symlog_kwargs = dict(linthresh=scales[scales > 0][0], linscale=0.5) + + # Run through thresholds: + for j in range(thresh_rel.size): + ax = axes[j, i] + # Plot swarm of feature-specific intensity curves: + handles = ax.plot(scales, measure[:, :, j], lw=lw['swarm']) + assign_colors(handles, config['k_specs'][:, 0], kern_colors) + reorder_by_sd(handles, measure[:, :, j]) + + # Plot single compressed intensity curve: + compressed = np.median(measure[:, :, j], axis=1) + ax.plot(scales, compressed, **median_kwargs) + + # Plot distribution of saturation levels: + inset = ax.inset_axes(inset_y_bounds) + inset.set_ylim(0, 1) + inset.axis('off') + y_dist(inset, measure[-1, :, j], **y_dist_kwargs) + + # Plot distribution of saturation points: + crit_inds = np.array(get_saturation(measure[:, :, j], **plateau_settings)[1]) + if np.isnan(crit_inds).sum(): + print(f'WARNING: No saturation points found for {species} at threshold {thresh_rel[j]}') + crit_inds = crit_inds[~np.isnan(crit_inds)].astype(int) + crit_scales = scales[crit_inds] + inset = ax.inset_axes(inset_x_bounds) + inset.set_xlim(scales[0], scales[-1]) + inset.set_xscale('symlog', **symlog_kwargs) + hide_axis(inset, 'left') + if j < thresh_rel.size - 1: + hide_ticks(inset, 'bottom') + x_dist(inset, crit_scales, **x_dist_kwargs) + + if j > 0: + # Plot single saturation point: + crit_ind = get_saturation(compressed, **plateau_settings)[1] + crit_scale = scales[crit_ind] + inset.plot(crit_scale, 0, **plateau_dot_kwargs) + +# Posthocs: +axes[0, 0].set_xscale('symlog', **symlog_kwargs) +axes[0, 0].set_xlim(scales[0], scales[-1]) + +if save_path is not None: + fig.savefig(save_path) +print('Done.') +plt.show() + + + diff --git a/python/fig_invariance_field.py b/python/fig_invariance_field.py index 6c906b3..efe91d3 100644 --- a/python/fig_invariance_field.py +++ b/python/fig_invariance_field.py @@ -5,11 +5,12 @@ from itertools import product from thunderhopper.filetools import search_files from thunderhopper.modeltools import load_data from thunderhopper.filtertools import find_kern_specs -from misc_functions import get_saturation +from misc_functions import get_saturation, reduce_kernel_set, exclude_zero_scale,\ + divide_by_zero, x_dist, y_dist from color_functions import load_colors -from plot_functions import hide_axis, reorder_by_sd, ylimits, super_xlabel,\ - ylabel, title_subplot, plot_line, time_bar,\ - assign_colors, letter_subplot, letter_subplots +from plot_functions import hide_axis, reorder_by_sd, ylimits, super_xlabel, ylabel, title_subplot,\ + plot_line, strip_zeros, time_bar, assign_colors,\ + letter_subplot, letter_subplots, hide_ticks from IPython import embed def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs): @@ -17,25 +18,16 @@ def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs): handles = [] for i, ax in enumerate(axes): handles.append(plot_line(ax, time, snippets[:, ..., i], - ymin=ymin, ymax=ymax, **kwargs)) + ymin=ymin, ymax=ymax, **kwargs)) return handles -def plot_curves(ax, scales, measures, fill_kwargs={}, **kwargs): +def plot_curves(ax, scales, measures, **kwargs): if measures.ndim == 1: - ax.plot(scales, measures, **kwargs)[0] - return measures - median_measure = np.median(measures, axis=1) - spread_measure = [np.percentile(measures, 25, axis=1), - np.percentile(measures, 75, axis=1)] - ax.plot(scales, median_measure, **kwargs)[0] - ax.fill_between(scales, *spread_measure, **fill_kwargs) - return median_measure - -def reduce_kernel_set(data, inds, keyword, stages=['conv', 'feat']): - for stage in stages: - key = f'{keyword}_{stage}' - data[key] = data[key][:, inds, ...] - return data + handles = ax.plot(scales, measures, **kwargs) + return handles, measures + median_measure = np.nanmedian(measures, axis=1) + line_handle = ax.plot(scales, median_measure, **kwargs)[0] + return line_handle, median_measure def crop_noise_snippets(snippets, nin, nout, stages=['filt', 'env', 'log', 'inv', 'conv', 'feat']): half_offset = int((nin - nout) / 2) @@ -64,19 +56,12 @@ save_path = '../figures/fig_invariance_field.pdf' offset_distance = 10 # centimeter # SUBSET SETTINGS: -types = np.array([1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10]) -sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016, 0.032]) +types = np.array([1, -1, 2, -2, 3, -3, 4, -4]) # types = [1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10] +sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016]) # sigmas = [0.001, 0.002, 0.004, 0.008, 0.016, 0.032] -kernels = np.array([ - [1, 0.002], - [-1, 0.002], - [2, 0.004], - [-2, 0.004], - [3, 0.032], - [-3, 0.032] -]) kernels = None +reduce_kernels = any(var is not None for var in [kernels, types, sigmas]) # GRAPH SETTINGS: fig_kwargs = dict( diff --git a/python/fig_invariance_field_backup.py b/python/fig_invariance_field_backup.py new file mode 100644 index 0000000..6c906b3 --- /dev/null +++ b/python/fig_invariance_field_backup.py @@ -0,0 +1,433 @@ +import plotstyle_plt +import numpy as np +import matplotlib.pyplot as plt +from itertools import product +from thunderhopper.filetools import search_files +from thunderhopper.modeltools import load_data +from thunderhopper.filtertools import find_kern_specs +from misc_functions import get_saturation +from color_functions import load_colors +from plot_functions import hide_axis, reorder_by_sd, ylimits, super_xlabel,\ + ylabel, title_subplot, plot_line, time_bar,\ + assign_colors, letter_subplot, letter_subplots +from IPython import embed + +def plot_snippets(axes, time, snippets, ymin=None, ymax=None, **kwargs): + ymin, ymax = ylimits(snippets, minval=ymin, maxval=ymax, pad=0.05) + handles = [] + for i, ax in enumerate(axes): + handles.append(plot_line(ax, time, snippets[:, ..., i], + ymin=ymin, ymax=ymax, **kwargs)) + return handles + +def plot_curves(ax, scales, measures, fill_kwargs={}, **kwargs): + if measures.ndim == 1: + ax.plot(scales, measures, **kwargs)[0] + return measures + median_measure = np.median(measures, axis=1) + spread_measure = [np.percentile(measures, 25, axis=1), + np.percentile(measures, 75, axis=1)] + ax.plot(scales, median_measure, **kwargs)[0] + ax.fill_between(scales, *spread_measure, **fill_kwargs) + return median_measure + +def reduce_kernel_set(data, inds, keyword, stages=['conv', 'feat']): + for stage in stages: + key = f'{keyword}_{stage}' + data[key] = data[key][:, inds, ...] + return data + +def crop_noise_snippets(snippets, nin, nout, stages=['filt', 'env', 'log', 'inv', 'conv', 'feat']): + half_offset = int((nin - nout) / 2) + segment = np.arange(half_offset, half_offset + nout) + for stage in stages: + key = f'snip_{stage}' + snippets[key] = snippets[key][segment, ...] + return snippets + + +# GENERAL SETTINGS: +search_target = 'Pseudochorthippus_parallelus' +stages = ['filt', 'env', 'log', 'inv', 'conv', 'feat'] +song_example = 'Pseudochorthippus_parallelus_micarray-short_JJ_20240815T160355-20240815T160755-1m10s690ms-1m13s614ms' +noise_example = 'merged_noise' +song_path = '../data/inv/field/song/' +noise_path = '../data/inv/field/noise/' +raw_path = search_files(search_target, incl='unnormed', dir=song_path + 'condensed/')[0] +base_path = search_files(search_target, incl='base', dir=song_path + 'condensed/')[0] +range_path = search_files(search_target, incl='range', dir=song_path + 'condensed/')[0] +song_snip_path = search_files(song_example, dir=song_path)[0] +noise_snip_path = search_files(noise_example, dir=noise_path)[0] +save_path = '../figures/fig_invariance_field.pdf' + +# ANALYSIS SETTINGS: +offset_distance = 10 # centimeter + +# SUBSET SETTINGS: +types = np.array([1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10]) +sigmas = np.array([0.001, 0.002, 0.004, 0.008, 0.016, 0.032]) +# types = [1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10] +# sigmas = [0.001, 0.002, 0.004, 0.008, 0.016, 0.032] +kernels = np.array([ + [1, 0.002], + [-1, 0.002], + [2, 0.004], + [-2, 0.004], + [3, 0.032], + [-3, 0.032] +]) +kernels = None + +# GRAPH SETTINGS: +fig_kwargs = dict( + figsize=(32/2.54, 32/2.54), +) +super_grid_kwargs = dict( + nrows=2, + ncols=1, + wspace=0, + hspace=0, + left=0, + right=1, + bottom=0, + top=1, + height_ratios=[3, 2] +) +subfig_specs = dict( + snip=(0, 0), + big=(1, 0), +) +snip_grid_kwargs = dict( + nrows=len(stages), + ncols=None, + wspace=0.1, + hspace=0.4, + left=0.11, + right=0.98, + bottom=0.08, + top=0.95 +) +big_grid_kwargs = dict( + nrows=1, + ncols=3, + wspace=0.4, + hspace=0, + left=snip_grid_kwargs['left'], + right=snip_grid_kwargs['right'], + bottom=0.13, + top=0.98 +) + +# PLOT SETTINGS: +fs = dict( + lab_norm=16, + lab_tex=20, + letter=22, + tit_norm=16, + tit_tex=20, + bar=16, +) +colors = load_colors('../data/stage_colors.npz') +conv_colors = load_colors('../data/conv_colors_all.npz') +feat_colors = load_colors('../data/feat_colors_all.npz') +lw = dict( + filt=0.25, + env=0.25, + log=0.25, + inv=0.25, + conv=0.25, + feat=1, + big=3, + plateau=1.5, +) +xlabels = dict( + big='distance [cm]', +) +ylabels = dict( + filt='$x_{\\text{filt}}$\n$[\\text{a.u.}]$', + env='$x_{\\text{env}}$\n$[\\text{a.u.}]$', + log='$x_{\\text{log}}$\n$[\\text{dB}]$', + inv='$x_{\\text{adapt}}$\n$[\\text{dB}]$', + conv='$c_i$\n$[\\text{dB}]$', + feat='$f_i$', + big=['measure', 'rel. measure', 'norm. measure'] +) +xlab_big_kwargs = dict( + y=0, + fontsize=fs['lab_norm'], + ha='center', + va='bottom', +) +ylab_snip_kwargs = dict( + x=0, + fontsize=fs['lab_tex'], + rotation=0, + ha='left', + va='center' +) +ylab_big_kwargs = dict( + x=-0.2, + fontsize=fs['lab_norm'], + ha='center', + va='bottom', +) +yloc = dict( + filt=0.03, + env=0.01, + log=50, + inv=20, + conv=1, + feat=1, +) +title_kwargs = dict( + x=0.5, + yref=1, + ha='center', + va='top', + fontsize=fs['tit_norm'], +) +letter_snip_kwargs = dict( + x=0, + yref=0.5, + ha='left', + va='center', + fontsize=fs['letter'], +) +letter_big_kwargs = dict( + x=0, + y=1, + ha='left', + va='bottom', + fontsize=fs['letter'], +) +song_bar_time = 1 +song_bar_kwargs = dict( + dur=song_bar_time, + y0=-0.25, + y1=-0.1, + xshift=1, + color='k', + lw=0, + clip_on=False, + text_pos=(-0.1, 0.5), + text_str=f'${song_bar_time}\\,\\text{{s}}$', + text_kwargs=dict( + fontsize=fs['bar'], + ha='right', + va='center', + ) +) +noise_bar_time = 0.5 +noise_bar_kwargs = song_bar_kwargs.copy() +noise_bar_kwargs['dur'] = noise_bar_time +noise_bar_kwargs['text_str'] = f'${int(1000 * noise_bar_time)}\\,\\text{{ms}}$' +plateau_settings = dict( + low=0.05, + high=0.95, + first=True, + last=True, + condense=None, +) +plateau_line_kwargs = dict( + lw=lw['plateau'], + ls='--', + zorder=1, +) +plateau_dot_kwargs = dict( + marker='o', + markersize=8, + markeredgewidth=1, + clip_on=False, +) + +# EXECUTION: + +# Load raw (unnormed) invariance data: +data, config = load_data(raw_path, files='distances', keywords='mean') +dists = data['distances'] + offset_distance + +# Load snippet data: +song_snip, _ = load_data(song_snip_path, keywords='snip') +t_song = np.arange(song_snip['snip_filt'].shape[0]) / config['rate'] +noise_snip, _ = load_data(noise_snip_path, keywords='snip') +noise_snip = crop_noise_snippets(noise_snip, noise_snip['snip_filt'].shape[0], t_song.size) +t_noise = np.arange(noise_snip['snip_filt'].shape[0]) / config['rate'] +snip_dists = ['noise'] + [f'{int(d)}$\\,$cm' for d in dists] + +# Optional kernel subset: +reduce_kernels = False +if any(var is not None for var in [kernels, types, sigmas]): + kern_inds = find_kern_specs(config['k_specs'], kernels, types, sigmas) + data = reduce_kernel_set(data, kern_inds, keyword='mean') + song_snip = reduce_kernel_set(song_snip, kern_inds, keyword='snip') + noise_snip = reduce_kernel_set(noise_snip, kern_inds, keyword='snip') + config['k_specs'] = config['k_specs'][kern_inds, :] + config['kernels'] = config['kernels'][:, kern_inds] + reduce_kernels = True + +# Adjust grid parameters: +snip_grid_kwargs['ncols'] = len(snip_dists) + +# Prepare overall graph: +fig = plt.figure(**fig_kwargs) +super_grid = fig.add_gridspec(**super_grid_kwargs) + +# Prepare stage-specific snippet axes: +snip_subfig = fig.add_subfigure(super_grid[subfig_specs['snip']]) +snip_grid = snip_subfig.add_gridspec(**snip_grid_kwargs) +snip_axes = np.zeros((snip_grid.nrows, snip_grid.ncols), dtype=object) +for i, j in product(range(snip_grid.nrows), range(snip_grid.ncols)): + ax = snip_subfig.add_subplot(snip_grid[i, j]) + ax.yaxis.set_major_locator(plt.MultipleLocator(yloc[stages[i]])) + hide_axis(ax, 'bottom') + if i == 0: + title = title_subplot(ax, snip_dists[j], ref=snip_subfig, **title_kwargs) + if j == 0: + ax.set_xlim(t_noise[0], t_noise[-1]) + ylabel(ax, ylabels[stages[i]], **ylab_snip_kwargs, transform=snip_subfig.transSubfigure) + else: + ax.set_xlim(t_song[0], t_song[-1]) + hide_axis(ax, 'left') + snip_axes[i, j] = ax +time_bar(snip_axes[-1, -1], **song_bar_kwargs) +# time_bar(snip_axes[-1, 0], **noise_bar_kwargs) +letter_subplot(snip_subfig, 'a', ref=title, **letter_snip_kwargs) + +# Prepare analysis axes: +big_subfig = fig.add_subfigure(super_grid[subfig_specs['big']]) +big_grid = big_subfig.add_gridspec(**big_grid_kwargs) +big_axes = np.zeros((big_grid.ncols,), dtype=object) +for i in range(big_grid.ncols): + ax = big_subfig.add_subplot(big_grid[0, i]) + ax.set_xlim(dists[0], 0) + # ax.set_xscale('symlog', linthresh=offset_distance, linscale=0.5) + ax.set_yscale('symlog', linthresh=0.01, linscale=0.1) + ylabel(ax, ylabels['big'][i], **ylab_big_kwargs) + # if i < (big_grid.ncols - 1): + # ax.set_ylim(scales[0], scales[-1]) + # else: + # ax.set_ylim(0, 1) + big_axes[i] = ax +super_xlabel(xlabels['big'], big_subfig, big_axes[0], big_axes[-1], **xlab_big_kwargs) +letter_subplots(big_axes, 'bcd', **letter_big_kwargs) + +if True: + # Plot filtered snippets: + plot_snippets(snip_axes[0, 1:], t_song, song_snip['snip_filt'], + c=colors['filt'], lw=lw['filt']) + plot_line(snip_axes[0, 0], t_noise, noise_snip['snip_filt'][:, 0], + *snip_axes[0, 1].get_ylim(), c=colors['filt'], lw=lw['filt']) + + # Plot envelope snippets: + plot_snippets(snip_axes[1, 1:], t_song, song_snip['snip_env'], + ymin=0, c=colors['env'], lw=lw['env']) + plot_line(snip_axes[1, 0], t_noise, noise_snip['snip_env'][:, 0], + *snip_axes[1, 1].get_ylim(), c=colors['env'], lw=lw['env']) + + # Plot logarithmic snippets: + plot_snippets(snip_axes[2, 1:], t_song, song_snip['snip_log'], + c=colors['log'], lw=lw['log']) + plot_line(snip_axes[2, 0], t_noise, noise_snip['snip_log'][:, 0], + *snip_axes[2, 1].get_ylim(), c=colors['log'], lw=lw['log']) + + # Plot invariant snippets: + plot_snippets(snip_axes[3, 1:], t_song, song_snip['snip_inv'], + c=colors['inv'], lw=lw['inv']) + plot_line(snip_axes[3, 0], t_noise, noise_snip['snip_inv'][:, 0], + *snip_axes[3, 1].get_ylim(), c=colors['inv'], lw=lw['inv']) + + # Plot kernel response snippets: + all_handles = plot_snippets(snip_axes[4, 1:], t_song, song_snip['snip_conv'], + c=colors['conv'], lw=lw['conv']) + for i, handles in enumerate(all_handles): + assign_colors(handles, config['k_specs'][:, 0], conv_colors) + reorder_by_sd(handles, song_snip['snip_conv'][..., i]) + handles = plot_line(snip_axes[4, 0], t_noise, noise_snip['snip_conv'][:, 0], + *snip_axes[4, 1].get_ylim(), c=colors['conv'], lw=lw['conv']) + assign_colors(handles, config['k_specs'][:, 0], conv_colors) + reorder_by_sd(handles, noise_snip['snip_conv'][:, 0]) + + # Plot feature snippets: + all_handles = plot_snippets(snip_axes[5, 1:], t_song, song_snip['snip_feat'], + ymin=0, ymax=1, c=colors['feat'], lw=lw['feat']) + for i, handles in enumerate(all_handles): + assign_colors(handles, config['k_specs'][:, 0], feat_colors) + reorder_by_sd(handles, song_snip['snip_feat'][..., i]) + handles = plot_line(snip_axes[5, 0], t_noise, noise_snip['snip_feat'][:, 0], + ymin=0, ymax=1, c=colors['feat'], lw=lw['feat']) + assign_colors(handles, config['k_specs'][:, 0], feat_colors) + reorder_by_sd(handles, noise_snip['snip_feat'][:, 0]) +del song_snip, noise_snip + +# Remember saturation points: +crit_inds, crit_dists = {}, {} + +# Unnormed measures: +for stage in stages: + # Plot average intensity measure across recordings: + curve = plot_curves(big_axes[0], dists, data[f'mean_{stage}'], + c=colors[stage], lw=lw['big'], + fill_kwargs=dict(color=colors[stage], alpha=0.25)) + # # Indicate saturation point: + # if stage in ['log', 'inv', 'conv', 'feat']: + # ind = get_saturation(curve, **plateau_settings)[1] + # dist = dists[ind] + # big_axes[0].plot(dist, 0, c='w', alpha=1, zorder=5.5, **plateau_dot_kwargs, + # transform=big_axes[0].get_xaxis_transform()) + # big_axes[0].plot(dist, 0, mfc=colors[stage], mec='k', alpha=0.75, zorder=6, **plateau_dot_kwargs, + # transform=big_axes[0].get_xaxis_transform()) + # big_axes[0].vlines(dist, big_axes[0].get_ylim()[0], curve[ind], + # color=colors[stage], **plateau_line_kwargs) + # # Log saturation point: + # crit_inds[stage] = ind + # crit_dists[stage] = dist +del data + +# Noise baseline-related measures: +data, _ = load_data(base_path, files='scales', keywords='mean') +if reduce_kernels: + data = reduce_kernel_set(data, kern_inds, keyword='mean') +for stage in stages: + # Plot average intensity measure across recordings: + curve = plot_curves(big_axes[1], dists, data[f'mean_{stage}'], + c=colors[stage], lw=lw['big'], + fill_kwargs=dict(color=colors[stage], alpha=0.25)) + # Indicate saturation point: + # if stage in ['log', 'inv', 'conv', 'feat']: + # ind, dist = crit_inds[stage], crit_dists[stage] + # big_axes[1].plot(dist, 0, c='w', alpha=1, zorder=5.5, **plateau_dot_kwargs, + # transform=big_axes[1].get_xaxis_transform()) + # big_axes[1].plot(dist, 0, mfc=colors[stage], mec='k', alpha=0.75, zorder=6, **plateau_dot_kwargs, + # transform=big_axes[1].get_xaxis_transform()) + # big_axes[1].vlines(dist, big_axes[1].get_ylim()[0], curve[ind], + # color=colors[stage], **plateau_line_kwargs) +del data + +# Min-max normalized measures: +data, _ = load_data(range_path, files='scales', keywords='mean') +if reduce_kernels: + data = reduce_kernel_set(data, kern_inds, keyword='mean') +for stage in stages: + # Plot average intensity measure across recordings: + curve = plot_curves(big_axes[2], dists, data[f'mean_{stage}'], + c=colors[stage], lw=lw['big'], + fill_kwargs=dict(color=colors[stage], alpha=0.25)) + + # # Indicate saturation point: + # if stage in ['log', 'inv', 'conv', 'feat']: + # ind, dist = crit_inds[stage], crit_dists[stage] + # big_axes[2].plot(dist, 0, c='w', alpha=1, zorder=5.5, **plateau_dot_kwargs, + # transform=big_axes[2].get_xaxis_transform()) + # big_axes[2].plot(dist, 0, mfc=colors[stage], mec='k', alpha=0.75, zorder=6, **plateau_dot_kwargs, + # transform=big_axes[2].get_xaxis_transform()) + # big_axes[2].vlines(dist, big_axes[2].get_ylim()[0], curve[ind], + # color=colors[stage], **plateau_line_kwargs) +del data + +# Save graph: +if save_path is not None: + fig.savefig(save_path) +plt.show() + +print('Done.') +embed() diff --git a/python/misc_functions.py b/python/misc_functions.py index 1eefa80..df0cbb3 100644 --- a/python/misc_functions.py +++ b/python/misc_functions.py @@ -112,17 +112,18 @@ def get_thresholds(data=None, path=None, perc=None, factor=None, factors = data['factors'][inds] return data['sds'] * factors, factors, data['percs'][inds, :] -def y_dist(ax, values, nbins=50, limits=None, log=False, cap=0.01, density=True, - line_kwargs={}, fill_kwargs={}): +def y_dist(ax, values, edges=None, nbins=50, limits=None, log=False, cap=0.01, + density=True, line_kwargs={}, fill_kwargs={}): # Get distribution: - if limits is None: - limits = np.array([np.nanmin(values), np.nanmax(values)]) - limits += np.array([-1.1, 1.1]) * (limits[1] - limits[0]) - if log: - limits[0] = max(limits[0], cap) - edges = np.geomspace(*limits, nbins + 1) - else: - edges = np.linspace(*limits, nbins + 1) + if edges is None: + if limits is None: + limits = np.array([np.nanmin(values), np.nanmax(values)]) + limits += np.array([-1.1, 1.1]) * (limits[1] - limits[0]) + if log: + limits[0] = max(limits[0], cap) + edges = np.geomspace(*limits, nbins + 1) + else: + edges = np.linspace(*limits, nbins + 1) centers = edges[:-1] + np.diff(edges) / 2 pdf, _ = np.histogram(values, bins=edges, density=density) @@ -132,17 +133,18 @@ def y_dist(ax, values, nbins=50, limits=None, log=False, cap=0.01, density=True, ax.set_xlim(0, pdf.max() * 1.05) return pdf, centers, line_handle, fill_handle -def x_dist(ax, values, nbins=50, limits=None, log=False, cap=0.01, density=True, - line_kwargs={}, fill_kwargs={}): +def x_dist(ax, values, edges=None, nbins=50, limits=None, log=False, cap=0.01, + density=True, line_kwargs={}, fill_kwargs={}): # Get distribution: - if limits is None: - limits = np.array([np.nanmin(values), np.nanmax(values)]) - limits += np.array([-1.1, 1.1]) * (limits[1] - limits[0]) - if log: - limits[0] = max(limits[0], cap) - edges = np.geomspace(*limits, nbins + 1) - else: - edges = np.linspace(*limits, nbins + 1) + if edges is None: + if limits is None: + limits = np.array([np.nanmin(values), np.nanmax(values)]) + limits += np.array([-1.1, 1.1]) * (limits[1] - limits[0]) + if log: + limits[0] = max(limits[0], cap) + edges = np.geomspace(*limits, nbins + 1) + else: + edges = np.linspace(*limits, nbins + 1) centers = edges[:-1] + np.diff(edges) / 2 pdf, _ = np.histogram(values, bins=edges, density=density) diff --git a/python/save_inv_data_full.py b/python/save_inv_data_full.py index d3045f3..fe5ff0e 100644 --- a/python/save_inv_data_full.py +++ b/python/save_inv_data_full.py @@ -11,12 +11,12 @@ from IPython import embed target_species = [ 'Chorthippus_biguttulus', 'Chorthippus_mollis', - 'Chrysochraon_dispar', + # 'Chrysochraon_dispar', # 'Euchorthippus_declivus', # 'Gomphocerippus_rufus', # 'Omocestus_rufipes', # 'Pseudochorthippus_parallelus', -][2] +][1] example_file = { 'Chorthippus_biguttulus': 'Chorthippus_biguttulus_GBC_94-17s73.1ms-19s977ms', 'Chorthippus_mollis': 'Chorthippus_mollis_DJN_41_T28C-46s4.58ms-1m15s697ms', diff --git a/python/save_kernel_colors.py b/python/save_kernel_colors.py index 8397e43..87ef3a0 100644 --- a/python/save_kernel_colors.py +++ b/python/save_kernel_colors.py @@ -3,20 +3,29 @@ from color_functions import load_colors, shade_colors # Settings: stages = ['conv', 'bi', 'feat'] -mode = ['subset', 'all'][1] +mode = ['subset', 'all'][0] if mode == 'subset': kern_types = np.array([1, -1, 2, -2, 3, -3, 4, -4]) - shade_factors = np.linspace(-0.6, 0.2, kern_types.size) + shade_factors = dict( + conv=[-0.6, 0.25], + bi=[-0.6, 0.25], + feat=[-0.5, 0.5] + ) elif mode == 'all': kern_types = np.array([1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10]) - shade_factors = np.linspace(-0.6, 0.6, kern_types.size) + shade_factors = dict( + conv=[-0.75, 0.25], + bi=[-0.75, 0.25], + feat=[-0.5, 0.5] + ) # Main colors: stage_colors = load_colors('../data/stage_colors.npz') # Execution: for stage in stages: - colors = shade_colors(stage_colors[stage], shade_factors) + factors = np.linspace(*shade_factors[stage], kern_types.size) + colors = shade_colors(stage_colors[stage], factors) colors = {str(k): c for k, c in zip(kern_types, colors)} print(f'\n{stage} colors:') print(colors)