diff --git a/figures/fig_features_cross_species.pdf b/figures/fig_features_cross_species.pdf new file mode 100644 index 0000000..c17d8b3 Binary files /dev/null and b/figures/fig_features_cross_species.pdf differ diff --git a/main.aux b/main.aux index 05bae50..1290e6c 100644 --- a/main.aux +++ b/main.aux @@ -262,36 +262,38 @@ \newlabel{fig:inv_full}{{8}{17}{}{}{}} \@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces \textbf {Step-wise emergence of intensity invariant song representation along the model pathway.} }}{18}{}\protected@file@percent } \newlabel{fig:inv_short}{{9}{18}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces \textbf {Step-wise emergence of intensity invariant song representation along the model pathway.} }}{19}{}\protected@file@percent } -\newlabel{fig:inv_field}{{10}{19}{}{}{}} -\newlabel{eq:pdf_split}{{15}{20}{}{}{}} -\newlabel{eq:feat_avg}{{16}{20}{}{}{}} -\newlabel{eq:feat_prop}{{17}{20}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces \textbf {Inter- and intraspecific feature variability.} }}{19}{}\protected@file@percent } +\newlabel{fig:cross_species}{{10}{19}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces \textbf {Step-wise emergence of intensity invariant song representation along the model pathway.} }}{20}{}\protected@file@percent } +\newlabel{fig:inv_field}{{11}{20}{}{}{}} +\newlabel{eq:pdf_split}{{15}{21}{}{}{}} +\newlabel{eq:feat_avg}{{16}{21}{}{}{}} +\newlabel{eq:feat_prop}{{17}{21}{}{}{}} \abx@aux@cite{0}{stumpner1991auditory} \abx@aux@segm{0}{0}{stumpner1991auditory} -\@writefile{toc}{\contentsline {section}{\numberline {4}Discriminating species-specific song\\patterns in feature space}{21}{}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {5}Conclusions \& outlook}{21}{}\protected@file@percent } -\abx@aux@page{73}{21} -\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces \textbf {} }}{23}{}\protected@file@percent } -\newlabel{}{{11}{23}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces \textbf {} }}{23}{}\protected@file@percent } -\newlabel{}{{12}{23}{}{}{}} +\@writefile{toc}{\contentsline {section}{\numberline {4}Discriminating species-specific song\\patterns in feature space}{22}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {5}Conclusions \& outlook}{22}{}\protected@file@percent } +\abx@aux@page{73}{22} +\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces \textbf {} }}{24}{}\protected@file@percent } +\newlabel{}{{12}{24}{}{}{}} \@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces \textbf {} }}{24}{}\protected@file@percent } \newlabel{}{{13}{24}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces \textbf {} }}{24}{}\protected@file@percent } -\newlabel{}{{14}{24}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces \textbf {} }}{25}{}\protected@file@percent } +\newlabel{}{{14}{25}{}{}{}} \@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces \textbf {} }}{25}{}\protected@file@percent } \newlabel{}{{15}{25}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces \textbf {} }}{25}{}\protected@file@percent } -\newlabel{}{{16}{25}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces \textbf {} }}{26}{}\protected@file@percent } +\newlabel{}{{16}{26}{}{}{}} \@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces \textbf {} }}{26}{}\protected@file@percent } \newlabel{}{{17}{26}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {18}{\ignorespaces \textbf {} }}{26}{}\protected@file@percent } -\newlabel{}{{18}{26}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {18}{\ignorespaces \textbf {} }}{27}{}\protected@file@percent } +\newlabel{}{{18}{27}{}{}{}} \@writefile{lof}{\contentsline {figure}{\numberline {19}{\ignorespaces \textbf {} }}{27}{}\protected@file@percent } \newlabel{}{{19}{27}{}{}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {20}{\ignorespaces \textbf {} }}{27}{}\protected@file@percent } -\newlabel{}{{20}{27}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {20}{\ignorespaces \textbf {} }}{28}{}\protected@file@percent } +\newlabel{}{{20}{28}{}{}{}} +\@writefile{lof}{\contentsline {figure}{\numberline {21}{\ignorespaces \textbf {} }}{28}{}\protected@file@percent } +\newlabel{}{{21}{28}{}{}{}} \gdef\svg@ink@ver@settings{{\m@ne }{inkscape}{\m@ne }} \abx@aux@read@bbl@mdfivesum{1380DC8C93D2855FDB132CC5A40AD52F} -\gdef \@abspage@last{27} +\gdef \@abspage@last{28} diff --git a/main.fdb_latexmk b/main.fdb_latexmk index cee0d04..4c90ea1 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" 1777482193.66376 0 +["biber main"] 1777306108.0762 "main.bcf" "main.bbl" "main" 1777557720.19398 0 "cite.bib" 1770904753.08918 27483 4290db0c91f7b5055e25472ef913f6b4 "" - "main.bcf" 1777482193.58667 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" + "main.bcf" 1777557720.11922 112931 2a478116d80ebb1ada7083a24facd6e3 "pdflatex" (generated) "main.bbl" "main.blg" (rewritten before read) -["pdflatex"] 1777482192.53139 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1777482193.664 0 +["pdflatex"] 1777557719.11318 "/home/hartling/phd/paper/paper_2025/main.tex" "main.pdf" "main" 1777557720.1942 0 "/etc/texmf/web2c/texmf.cnf" 1761560044.43676 475 c0e671620eb5563b2130f56340a5fde8 "" - "/home/hartling/phd/paper/paper_2025/main.tex" 1777448077.05934 52881 e18226ede44f18b9cf98e6344041bedb "" + "/home/hartling/phd/paper/paper_2025/main.tex" 1777554882.92499 53144 07c2f08efb91bd2468ab34aa57c132d9 "" "/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 "" @@ -153,6 +153,7 @@ "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1761648508 8213325 7fd20752ab46ff9aa583e4973d7433df "" "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_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 "" @@ -171,10 +172,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" 1777482193.58067 18677 56f36bb5fefb9703ee41dbf6e2b62286 "pdflatex" + "main.aux" 1777557720.11222 18884 222c10edd4cc01d3fc0fb20a437c4ed8 "pdflatex" "main.bbl" 1777306108.74822 91039 1380dc8c93d2855fdb132cc5a40ad52f "biber main" - "main.run.xml" 1777482193.58767 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" - "main.tex" 1777448077.05934 52881 e18226ede44f18b9cf98e6344041bedb "" + "main.run.xml" 1777557720.11922 2335 a049bc26a7f032e842ce55de5bc38328 "pdflatex" + "main.tex" 1777554882.92499 53144 07c2f08efb91bd2468ab34aa57c132d9 "" (generated) "main.aux" "main.bcf" diff --git a/main.fls b/main.fls index 270c065..7e438db 100644 --- a/main.fls +++ b/main.fls @@ -318,6 +318,11 @@ INPUT ./figures/fig_invariance_short_Omocestus_rufipes.pdf INPUT ./figures/fig_invariance_short_Omocestus_rufipes.pdf INPUT ./figures/fig_invariance_short_Omocestus_rufipes.pdf INPUT ./figures/fig_invariance_short_Omocestus_rufipes.pdf +INPUT ./figures/fig_features_cross_species.pdf +INPUT ./figures/fig_features_cross_species.pdf +INPUT ./figures/fig_features_cross_species.pdf +INPUT ./figures/fig_features_cross_species.pdf +INPUT ./figures/fig_features_cross_species.pdf INPUT ./figures/fig_invariance_field.pdf INPUT ./figures/fig_invariance_field.pdf INPUT ./figures/fig_invariance_field.pdf diff --git a/main.log b/main.log index 5940816..db73c64 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) 29 APR 2026 19:03 +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 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -832,70 +832,76 @@ Package pdftex.def Info: figures/fig_invariance_short_Omocestus_rufipes.pdf use [17 <./figures/fig_invariance_full_Omocestus_rufipes.pdf>] - + +File: figures/fig_features_cross_species.pdf Graphic file (type pdf) + +Package pdftex.def Info: figures/fig_features_cross_species.pdf used on input line 768. +(pdftex.def) Requested size: 483.69687pt x 483.69566pt. + [18 <./figures/fig_invariance_short_Omocestus_rufipes.pdf>] [19 <./figures/fig_features_cross_species.pdf>] + File: figures/fig_invariance_field.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_field.pdf used on input line 768. +Package pdftex.def Info: figures/fig_invariance_field.pdf used on input line 777. (pdftex.def) Requested size: 483.69687pt x 483.69566pt. - [18 <./figures/fig_invariance_short_Omocestus_rufipes.pdf>] [19 <./figures/fig_invariance_field.pdf>] [20 + [20 -] [21] - + <./figures/fig_invariance_field.pdf>] [21] [22] + File: figures/fig_noise_env_sd_conversion_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_noise_env_sd_conversion_appendix.pdf used on input line 927. +Package pdftex.def Info: figures/fig_noise_env_sd_conversion_appendix.pdf used on input line 936. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [22] - + [23] + File: figures/fig_invariance_rect-lp_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_rect-lp_appendix.pdf used on input line 936. +Package pdftex.def Info: figures/fig_invariance_rect-lp_appendix.pdf used on input line 945. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - + File: figures/fig_invariance_log-hp_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_log-hp_appendix.pdf used on input line 945. +Package pdftex.def Info: figures/fig_invariance_log-hp_appendix.pdf used on input line 954. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [23 <./figures/fig_noise_env_sd_conversion_appendix.pdf> <./figures/fig_invariance_rect-lp_appendix.pdf>] - + [24 <./figures/fig_noise_env_sd_conversion_appendix.pdf> <./figures/fig_invariance_rect-lp_appendix.pdf>] + File: figures/fig_saturation_log-hp_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_saturation_log-hp_appendix.pdf used on input line 954. +Package pdftex.def Info: figures/fig_saturation_log-hp_appendix.pdf used on input line 963. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - + File: figures/fig_invariance_thresh-lp_pure_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_thresh-lp_pure_appendix.pdf used on input line 963. +Package pdftex.def Info: figures/fig_invariance_thresh-lp_pure_appendix.pdf used on input line 972. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [24 <./figures/fig_invariance_log-hp_appendix.pdf> <./figures/fig_saturation_log-hp_appendix.pdf>] - + [25 <./figures/fig_invariance_log-hp_appendix.pdf> <./figures/fig_saturation_log-hp_appendix.pdf>] + File: figures/fig_invariance_thresh-lp_noise_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_invariance_thresh-lp_noise_appendix.pdf used on input line 972. +Package pdftex.def Info: figures/fig_invariance_thresh-lp_noise_appendix.pdf used on input line 981. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - + File: figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf used on input line 981. +Package pdftex.def Info: figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf used on input line 990. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [25 <./figures/fig_invariance_thresh-lp_pure_appendix.pdf> <./figures/fig_invariance_thresh-lp_noise_appendix.pdf>] - + [26 <./figures/fig_invariance_thresh-lp_pure_appendix.pdf> <./figures/fig_invariance_thresh-lp_noise_appendix.pdf>] + File: figures/fig_kernel_sd_perc_full_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_kernel_sd_perc_full_appendix.pdf used on input line 990. +Package pdftex.def Info: figures/fig_kernel_sd_perc_full_appendix.pdf used on input line 999. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - + File: figures/fig_kernel_sd_perc_short_appendix.pdf Graphic file (type pdf) -Package pdftex.def Info: figures/fig_kernel_sd_perc_short_appendix.pdf used on input line 999. +Package pdftex.def Info: figures/fig_kernel_sd_perc_short_appendix.pdf used on input line 1008. (pdftex.def) Requested size: 483.69687pt x 241.84782pt. - [26 <./figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf> <./figures/fig_kernel_sd_perc_full_appendix.pdf>] - + [27 <./figures/fig_kernel_sd_perc_thresh_lp_appendix.pdf> <./figures/fig_kernel_sd_perc_full_appendix.pdf>] + 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 1008. +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. - [27 <./figures/fig_kernel_sd_perc_short_appendix.pdf> <./figures/fig_kernel_sd_perc_field_appendix.pdf>] (./main.aux) + [28 <./figures/fig_kernel_sd_perc_short_appendix.pdf> <./figures/fig_kernel_sd_perc_field_appendix.pdf>] (./main.aux) *********** LaTeX2e <2023-11-01> patch level 1 L3 programming layer <2024-01-22> @@ -909,18 +915,18 @@ Package logreq Info: Writing requests to 'main.run.xml'. ) Here is how much of TeX's memory you used: - 20849 strings out of 474222 - 452796 string characters out of 5748732 + 20857 strings out of 474222 + 453153 string characters out of 5748732 1938975 words of memory out of 5000000 - 42839 multiletter control sequences out of 15000+600000 + 42847 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 (27 pages, 38753439 bytes). +Output written on main.pdf (28 pages, 38895611 bytes). PDF statistics: - 2414 PDF objects out of 2487 (max. 8388607) - 1082 compressed objects within 11 object streams + 2479 PDF objects out of 2487 (max. 8388607) + 1101 compressed objects within 12 object streams 0 named destinations out of 1000 (max. 500000) - 113 words of extra memory for PDF output out of 10000 (max. 10000000) + 118 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/main.pdf b/main.pdf index 78cc990..9b4ee74 100644 Binary files a/main.pdf and b/main.pdf differ diff --git a/main.synctex.gz b/main.synctex.gz index d76d2da..1a5b030 100644 Binary files a/main.synctex.gz and b/main.synctex.gz differ diff --git a/main.tex b/main.tex index 0f61a4e..eeebaca 100644 --- a/main.tex +++ b/main.tex @@ -763,6 +763,15 @@ the signal for reliable song recognition. \end{figure} \FloatBarrier +\begin{figure}[!ht] + \centering + \includegraphics[width=\textwidth]{figures/fig_features_cross_species.pdf} + \caption{\textbf{Inter- and intraspecific feature variability.} + } + \label{fig:cross_species} +\end{figure} +\FloatBarrier + \begin{figure}[!ht] \centering \includegraphics[width=\textwidth]{figures/fig_invariance_field.pdf} diff --git a/python/collect_inv_data_full.py b/python/collect_inv_data_full.py index 4541c30..5a72030 100644 --- a/python/collect_inv_data_full.py +++ b/python/collect_inv_data_full.py @@ -9,9 +9,9 @@ target_species = [ # 'Chorthippus_mollis', # 'Chrysochraon_dispar', # 'Euchorthippus_declivus', - # 'Gomphocerippus_rufus', + 'Gomphocerippus_rufus', 'Omocestus_rufipes', - # 'Pseudochorthippus_parallelus', + 'Pseudochorthippus_parallelus', ] stages = ['filt', 'env', 'log', 'inv', 'conv', 'feat'] search_path = '../data/inv/full/' diff --git a/python/fig_features_cross_species.py b/python/fig_features_cross_species.py new file mode 100644 index 0000000..1fb6405 --- /dev/null +++ b/python/fig_features_cross_species.py @@ -0,0 +1,425 @@ +import plotstyle_plt +import numpy as np +import matplotlib.pyplot as plt +from itertools import product +from scipy.stats import ttest_ind +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 +from color_functions import load_colors +from plot_functions import hide_ticks, xlabel, ylabel +from IPython import embed + + +# GENERAL SETTINGS: +cross_species = [ + # 'Chorthippus_biguttulus', + # 'Chorthippus_mollis', + # 'Chrysochraon_dispar', + # 'Euchorthippus_declivus', + 'Gomphocerippus_rufus', + 'Omocestus_rufipes', + 'Pseudochorthippus_parallelus', +] +n_spec = len(cross_species) +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' +} +in_species = [ + 'Chorthippus_biguttulus', + 'Chorthippus_mollis', + 'Chrysochraon_dispar', + 'Euchorthippus_declivus', + 'Gomphocerippus_rufus', + 'Omocestus_rufipes', + 'Pseudochorthippus_parallelus', +][5] +save_path = '../figures/fig_features_cross_species.pdf' + + +# ANALYSIS SETTINGS: +thresh_rel = np.array([0, 0.5, 1, 1.5, 2, 2.5, 3])[4] +single_spec_file = True # Only use example files for cross-species comparison +equalize_spec_files = False # Prune to minimum available across species +n_song = n_spec#None # Limit to n first songs of in-species dataset (None for all) +color_kern_types = True +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 = [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 = [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), +) +spec_grid_kwargs = dict( + wspace=0.1, + hspace=0.1, + left=0.07, + right=0.93, + bottom=0.07, + top=0.93, +) +song_grid_kwargs = dict( + wspace=0.1, + hspace=0.1, + left=spec_grid_kwargs['left'], + right=spec_grid_kwargs['right'], + bottom=spec_grid_kwargs['bottom'], + top=spec_grid_kwargs['top'], +) + +# PLOT SETTINGS: +kern_colors = load_colors('../data/feat_colors_all.npz') +fs = dict( + lab_norm=16, + lab_tex=20, + letter=22, + tit_norm=16, + tit_tex=20, + bar=16, +) +label_song_prefix = ['song ', ''][0] +xlab_low_kwargs = dict( + y=0.01, + fontsize=fs['lab_norm'], + ha='center', + va='bottom', + fontstyle='italic', +) +xlab_up_kwargs = dict( + y=0.99, + fontsize=fs['lab_norm'], + ha='center', + va='top', +) +ylab_low_kwargs = dict( + x=0.01, + fontsize=fs['lab_norm'], + ha='center', + va='top', + fontstyle='italic', +) +ylab_up_kwargs = dict( + x=0.99, + rotation=270, + fontsize=fs['lab_norm'], + ha='center', + va='top', +) +loc = 0.5 +dot_spec_kwargs = dict( + ls='none', + marker='o', + mec='w', + ms=6, + mew=0.5, + alpha=1, + zorder=2, +) +dot_song_kwargs = dict( + ls='none', + marker='o', + mec='w', + ms=6, + mew=0.5, + alpha=1, + zorder=2, +) +if not color_kern_types: + dot_spec_kwargs['mfc'] = 'k' + dot_song_kwargs['mfc'] = 'k' +diag_fig_kwargs = dict( + c='k', + lw=1, + ls='-' +) +diag_ax_kwargs = dict( + c='k', + lw=1, + ls='-', + zorder=3, +) +text_spec_kwargs = dict( + x=0.05, + y=0.95, + ha='left', + va='top', + fontsize=16, +) +text_song_kwargs = dict( + x=0, + y=0.95, + ha='left', + va='top', + fontsize=16, +) +text_spec_prefix = '$\\rho\\,=\\,$' +text_song_prefix = ['$\\rho\\,=\\,$', ''][0] +if test_regression: + test_ax_side = 0.15 + test_ax_bounds = [ + song_grid_kwargs['right'] - test_ax_side, + spec_grid_kwargs['bottom'], + test_ax_side, + test_ax_side + ] + xlab_test = '$\\rho$' + ylab_test = '$\\text{PDF}_{\\rho}$' + xloc_test = 0.5 + yloc_test = 10 + ylab_test_kwargs = dict( + x=-0.3, + fontsize=fs['lab_norm'], + ha='center', + va='bottom', + ) + nbins = 10 + spec_color = 'darkorchid' + song_color = 'goldenrod' + bar_kwargs = dict( + width=0.95, + alpha=0.75, + ) + mean_kwargs = dict( + ls='--', + lw=1, + ) + leg_kwargs = dict( + ncols=1, + loc='lower center', + bbox_to_anchor=(0, 1.05, 1, 0.5), + frameon=False, + prop=dict( + size=14, + ), + borderpad=0, + borderaxespad=0, + handlelength=1, + columnspacing=1, + handletextpad=0.5, + labelspacing=0.1 + ) + + +# EXECUTION: + +# Gather cross-species data: +spec_data, min_files = {}, np.inf +for species in cross_species: + # Load species data: + if single_spec_file: + path = search_files(example_files[species], dir='../data/inv/full/')[0] + else: + path = search_files(species, dir='../data/inv/full/collected/')[0] + data, config = load_data(path, ['measure_feat', 'thresh_rel']) + # Reduce to single threshold, last scale, optional kernel subset: + thresh_ind = np.nonzero(data['thresh_rel'] == thresh_rel)[0][0] + kern_inds = slice(None) + if reduce_kernels: + kern_inds = find_kern_specs(config['k_specs'], kernels, types, sigmas) + config['kernels'] = config['kernels'][:, kern_inds] + config['k_specs'] = config['k_specs'][kern_inds, :] + spec_data[species] = data['measure_feat'][-1, kern_inds, thresh_ind, ...] + if single_spec_file: + # Ensure consistent shape (features, files=1): + spec_data[species] = spec_data[species][..., None] + # Update number of possible comparisons: + min_files = min(min_files, spec_data[species].shape[-1]) + +if equalize_spec_files and not single_spec_file: + # Equalize number of files across species: + spec_data = {spec: feat[:, :min_files] for spec, feat in spec_data.items()} + +# Gather in-species data: +paths = search_files(in_species, dir='../data/inv/full/') +if n_song is not None: + paths = paths[:n_song] +else: + n_song = len(paths) +song_data = np.zeros((n_song, config['k_specs'].shape[0])) +for i, path in enumerate(paths): + # Load song-specific dataset: + data, config = load_data(path, ['measure_feat', 'thresh_rel']) + # Reduce to single threshold, last scale, optional kernel subset: + thresh_ind = np.nonzero(data['thresh_rel'] == thresh_rel)[0][0] + kern_inds = slice(None) + if reduce_kernels: + kern_inds = find_kern_specs(config['k_specs'], kernels, types, sigmas) + config['kernels'] = config['kernels'][:, kern_inds] + config['k_specs'] = config['k_specs'][kern_inds, :] + song_data[i] = data['measure_feat'][-1, kern_inds, thresh_ind] + +# Prepare graph: +fig = plt.figure(**fig_kwargs) +spec_grid = fig.add_gridspec(nrows=n_spec, ncols=n_spec, **spec_grid_kwargs) +song_grid = fig.add_gridspec(nrows=n_song, ncols=n_song, **song_grid_kwargs) +# fig.add_artist(plt.Line2D([0, 1], [1, 0], **diag_fig_kwargs)) + +# Prepare cross-species axes: +spec_labels = [shorten_species(spec) for spec in cross_species] +spec_axes = np.zeros((n_spec, n_spec), dtype=object) +for i, j in product(range(n_spec), range(n_spec)): + if i <= j: + continue + # Lower trianglular: + ax = fig.add_subplot(spec_grid[i, j]) + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.yaxis.set_major_locator(plt.MultipleLocator(loc)) + ax.xaxis.set_major_locator(plt.MultipleLocator(loc)) + # Indicate subplot diagonal: + ax.plot([0, 1], [0, 1], **diag_ax_kwargs) + # Adjust: + if j > 0: + hide_ticks(ax, 'left') + if i < n_spec - 1: + hide_ticks(ax, 'bottom') + if j == 0: + ylabel(ax, spec_labels[i], transform=fig.transFigure, **ylab_low_kwargs) + if i == n_spec - 1: + xlabel(ax, spec_labels[j], transform=fig.transFigure, **xlab_low_kwargs) + spec_axes[i, j] = ax + +# Prepare in-species axes: +song_labels = [label_song_prefix + f'{i}' for i in range(1, n_song + 1)] +song_axes = np.zeros((n_song, n_song), dtype=object) +for i, j in product(range(n_song), range(n_song)): + if i >= j: + continue + # Upper triangular: + ax = fig.add_subplot(song_grid[i, j]) + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.yaxis.set_major_locator(plt.MultipleLocator(loc)) + ax.xaxis.set_major_locator(plt.MultipleLocator(loc)) + ax.spines[['top', 'right']].set_visible(True) + ax.spines[['bottom', 'left']].set_visible(False) + ax.yaxis.set_label_position('right') + ax.yaxis.tick_right() + ax.xaxis.set_label_position('top') + ax.xaxis.tick_top() + # Indicate subplot diagonal: + ax.plot([0, 1], [0, 1], **diag_ax_kwargs) + # Adjust: + if i > 0: + hide_ticks(ax, 'top') + if j < n_song - 1: + hide_ticks(ax, 'right') + if i == 0: + xlabel(ax, song_labels[j], transform=fig.transFigure, **xlab_up_kwargs) + if j == n_song - 1: + ylabel(ax, song_labels[i], transform=fig.transFigure, **ylab_up_kwargs) + song_axes[i, j] = ax + +# Remember coefficients: +if calculate_regression: + spec_regs, song_regs = [], [] + +# Plot cross-species comparisons: +for x, y in product(range(n_spec), range(n_spec)): + if x >= y: + continue + # Get axis and data: + ax = spec_axes[y, x] + x_spec = spec_data[cross_species[x]] + y_spec = spec_data[cross_species[y]] + x_reg, y_reg = [], [] + # Plot features of species 1 against species 2 (all files cross-wise): + for i, j in product(range(x_spec.shape[-1]), range(y_spec.shape[-1])): + if color_kern_types: + for k, (f1, f2) in enumerate(zip(x_spec[:, i], y_spec[:, j])): + c = kern_colors[str(int(config['k_specs'][k, 0]))] + ax.plot(f1, f2, mfc=c, **dot_spec_kwargs) + else: + ax.plot(x_spec[:, i], y_spec[:, j], **dot_spec_kwargs) + # Accumulate value pairs: + if calculate_regression: + x_reg.append(x_spec[:, i]) + y_reg.append(y_spec[:, j]) + # Get regression coefficient: + if calculate_regression: + rho = np.corrcoef(np.concatenate(x_reg), np.concatenate(y_reg))[0, 1] + ax.text(s=text_spec_prefix + f'{rho:.2f}', transform=ax.transAxes, **text_spec_kwargs) + spec_regs.append(rho) + # print('\nAxis position: ', (y, x)) + # print(cross_species[x], '(x) vs.', cross_species[y], '(y)') + +# Plot in-species comparisons: +for x, y in product(range(n_song), range(n_song)): + if x <= y: + continue + # Get axis and data: + ax = song_axes[y, x] + x_song = song_data[x] + y_song = song_data[y] + # Plot features of song 1 against song 2: + if color_kern_types: + for i, (f1, f2) in enumerate(zip(x_song, y_song)): + c = kern_colors[str(int(config['k_specs'][i, 0]))] + ax.plot(f1, f2, mfc=c, **dot_song_kwargs) + else: + ax.plot(x_song, y_song, **dot_song_kwargs) + # Get regression coefficient: + if calculate_regression: + rho = np.corrcoef(x_song, y_song)[0, 1] + ax.text(s=text_song_prefix + f'{rho:.2f}', transform=ax.transAxes, **text_song_kwargs) + song_regs.append(rho) + # print('\nAxis position: ', (y, x)) + # print(f'Song {song_labels[x]} (x) vs. Song {song_labels[y]} (y)') + +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.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) + # 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) +plt.show() + + + + + diff --git a/python/save_inv_data_full.py b/python/save_inv_data_full.py index d10f298..d3045f3 100644 --- a/python/save_inv_data_full.py +++ b/python/save_inv_data_full.py @@ -12,11 +12,11 @@ target_species = [ 'Chorthippus_biguttulus', 'Chorthippus_mollis', 'Chrysochraon_dispar', - 'Euchorthippus_declivus', - 'Gomphocerippus_rufus', - 'Omocestus_rufipes', - 'Pseudochorthippus_parallelus', -][4] + # 'Euchorthippus_declivus', + # 'Gomphocerippus_rufus', + # 'Omocestus_rufipes', + # 'Pseudochorthippus_parallelus', +][2] example_file = { 'Chorthippus_biguttulus': 'Chorthippus_biguttulus_GBC_94-17s73.1ms-19s977ms', 'Chorthippus_mollis': 'Chorthippus_mollis_DJN_41_T28C-46s4.58ms-1m15s697ms',