From 7f17de27488c8c22c199996fe148f6ac11506b09 Mon Sep 17 00:00:00 2001 From: wendtalexander Date: Wed, 25 Jan 2023 17:47:00 +0100 Subject: [PATCH] adding plot changes --- code/plot_chirp_size.py | 165 +++++++++++++++++++++------- poster/figs/chirps_winner_loser.pdf | Bin 15606 -> 15996 bytes 2 files changed, 127 insertions(+), 38 deletions(-) diff --git a/code/plot_chirp_size.py b/code/plot_chirp_size.py index 894a80b..3547c17 100644 --- a/code/plot_chirp_size.py +++ b/code/plot_chirp_size.py @@ -4,6 +4,7 @@ import os import numpy as np import matplotlib.pyplot as plt +from scipy.stats import pearsonr, spearmanr from thunderfish.powerspectrum import decibel from IPython import embed @@ -12,6 +13,7 @@ from modules.logger import makeLogger from modules.plotstyle import PlotStyle from modules.behaviour_handling import Behavior, correct_chasing_events + ps = PlotStyle() logger = makeLogger(__name__) @@ -50,6 +52,7 @@ def get_chirp_size(folder_name, Behavior, order_meta_df, id_meta_df): folder_row = order_meta_df[order_meta_df['recording'] == foldername] fish1 = folder_row['fish1'].values[0].astype(int) fish2 = folder_row['fish2'].values[0].astype(int) + winner = folder_row['winner'].values[0].astype(int) groub = folder_row['group'].values[0].astype(int) size_fish1_row = id_meta_df[(id_meta_df['group'] == groub) & ( @@ -59,32 +62,57 @@ def get_chirp_size(folder_name, Behavior, order_meta_df, id_meta_df): size_winners = [size_fish1_row[col].values[0] for col in ['l1', 'l2', 'l3']] - mean_size_winner = np.nanmean(size_winners) + size_fish1 = np.nanmean(size_winners) size_losers = [size_fish2_row[col].values[0] for col in ['l1', 'l2', 'l3']] - mean_size_loser = np.nanmean(size_losers) + size_fish2 = np.nanmean(size_losers) + if winner == fish1: + if size_fish1 > size_fish2: + size_diff_bigger = size_fish1 - size_fish2 + size_diff_smaller = size_fish2 - size_fish1 + + elif size_fish1 < size_fish2: + size_diff_bigger = size_fish1 - size_fish2 + size_diff_smaller = size_fish2 - size_fish1 + else: + size_diff_bigger = np.nan + size_diff_smaller = np.nan + winner_fish_id = np.nan + loser_fish_id = np.nan + return size_diff_bigger, size_diff_smaller, winner_fish_id, loser_fish_id - if mean_size_winner > mean_size_loser: - size_diff_bigger = mean_size_winner - mean_size_loser - size_diff_smaller = mean_size_loser - mean_size_winner winner_fish_id = folder_row['rec_id1'].values[0] loser_fish_id = folder_row['rec_id2'].values[0] - elif mean_size_winner < mean_size_loser: - size_diff_bigger = mean_size_loser - mean_size_winner - size_diff_smaller = mean_size_winner - mean_size_loser + elif winner == fish2: + if size_fish2 > size_fish1: + size_diff_bigger = size_fish2 - size_fish1 + size_diff_smaller = size_fish1 - size_fish2 + + elif size_fish2 < size_fish1: + size_diff_bigger = size_fish2 - size_fish1 + size_diff_smaller = size_fish1 - size_fish2 + else: + size_diff_bigger = np.nan + size_diff_smaller = np.nan + winner_fish_id = np.nan + loser_fish_id = np.nan + return size_diff_bigger, size_diff_smaller, winner_fish_id, loser_fish_id + winner_fish_id = folder_row['rec_id2'].values[0] loser_fish_id = folder_row['rec_id1'].values[0] else: - size_diff = np.nan - winner_fish_id = np.nan - loser_fish_id = np.nan + size_diff_bigger = np.nan + size_diff_smaller = np.nan + winner_fish_id = np.nan + loser_fish_id = np.nan + return size_diff_bigger, size_diff_smaller, winner_fish_id, loser_fish_id chirp_winner = len( Behavior.chirps[Behavior.chirps_ids == winner_fish_id]) chirp_loser = len( Behavior.chirps[Behavior.chirps_ids == loser_fish_id]) - + return size_diff_bigger, chirp_winner, size_diff_smaller, chirp_loser @@ -92,27 +120,62 @@ def get_chirp_freq(folder_name, Behavior, order_meta_df): foldername = folder_name.split('/')[-2] folder_row = order_meta_df[order_meta_df['recording'] == foldername] - fish1 = folder_row['rec_id1'].values[0].astype(int) - fish2 = folder_row['rec_id2'].values[0].astype(int) + fish1 = folder_row['fish1'].values[0].astype(int) + fish2 = folder_row['fish2'].values[0].astype(int) + + fish1_freq = folder_row['rec_id1'].values[0].astype(int) + fish2_freq = folder_row['rec_id2'].values[0].astype(int) + winner = folder_row['winner'].values[0].astype(int) chirp_freq_fish1 = np.nanmedian( - Behavior.freq[Behavior.ident == fish1]) + Behavior.freq[Behavior.ident == fish1_freq]) chirp_freq_fish2 = np.nanmedian( - Behavior.freq[Behavior.ident == fish2]) + Behavior.freq[Behavior.ident == fish2_freq]) + + if winner == fish1: + if chirp_freq_fish1 > chirp_freq_fish2: + freq_diff_higher = chirp_freq_fish1 - chirp_freq_fish2 + freq_diff_lower = chirp_freq_fish2 - chirp_freq_fish1 + + elif chirp_freq_fish1 < chirp_freq_fish2: + freq_diff_higher = chirp_freq_fish1 - chirp_freq_fish2 + freq_diff_lower = chirp_freq_fish2 - chirp_freq_fish1 + else: + freq_diff_higher = np.nan + freq_diff_lower = np.nan + winner_fish_id = np.nan + loser_fish_id = np.nan - if chirp_freq_fish1 > chirp_freq_fish2: - freq_diff = chirp_freq_fish1 - chirp_freq_fish2 winner_fish_id = folder_row['rec_id1'].values[0] loser_fish_id = folder_row['rec_id2'].values[0] - elif chirp_freq_fish1 < chirp_freq_fish2: - freq_diff = chirp_freq_fish2 - chirp_freq_fish1 + elif winner == fish2: + if chirp_freq_fish2 > chirp_freq_fish1: + freq_diff_higher = chirp_freq_fish2 - chirp_freq_fish1 + freq_diff_lower = chirp_freq_fish1 - chirp_freq_fish2 + + elif chirp_freq_fish2 < chirp_freq_fish1: + freq_diff_higher = chirp_freq_fish2 - chirp_freq_fish1 + freq_diff_lower = chirp_freq_fish1 - chirp_freq_fish2 + else: + freq_diff_higher = np.nan + freq_diff_lower = np.nan + winner_fish_id = np.nan + loser_fish_id = np.nan + winner_fish_id = folder_row['rec_id2'].values[0] loser_fish_id = folder_row['rec_id1'].values[0] + else: + freq_diff_higher = np.nan + freq_diff_lower = np.nan + winner_fish_id = np.nan + loser_fish_id = np.nan - chirp_diff = len(Behavior.chirps[Behavior.chirps_ids == winner_fish_id]) - len( + chirp_winner = len( + Behavior.chirps[Behavior.chirps_ids == winner_fish_id]) + chirp_loser = len( Behavior.chirps[Behavior.chirps_ids == loser_fish_id]) - return freq_diff, chirp_diff + return freq_diff_higher, chirp_winner, freq_diff_lower, chirp_loser def main(datapath: str): @@ -128,8 +191,17 @@ def main(datapath: str): id_meta_df = read_csv(path_id_meta) chirps_winner = [] - size_diffs = [] - size_chirps_diffs = [] + + size_diffs_winner = [] + size_diffs_loser = [] + size_chirps_winner = [] + size_chirps_loser = [] + + freq_diffs_higher = [] + freq_diffs_lower = [] + freq_chirps_winner = [] + freq_chirps_loser = [] + chirps_loser = [] freq_diffs = [] freq_chirps_diffs = [] @@ -151,17 +223,32 @@ def main(datapath: str): foldername, bh, order_meta_df) chirps_winner.append(winner_chirp) chirps_loser.append(loser_chirp) - size_diff, chirp_diff = get_chirp_size( + + size_diff_bigger, chirp_winner, size_diff_smaller, chirp_loser = get_chirp_size( foldername, bh, order_meta_df, id_meta_df) - size_diffs.append(size_diff) - size_chirps_diffs.append(chirp_diff) - freq_diff, freq_chirps_diff = get_chirp_freq( + freq_diff_higher, chirp_freq_winner, freq_diff_lower, chirp_freq_loser = get_chirp_freq( foldername, bh, order_meta_df) - freq_diffs.append(freq_diff) - freq_chirps_diffs.append(freq_chirps_diff) + + freq_diffs_higher.append(freq_diff_higher) + freq_diffs_lower.append(freq_diff_lower) + freq_chirps_winner.append(chirp_freq_winner) + freq_chirps_loser.append(chirp_freq_loser) - fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(22*ps.cm, 12*ps.cm), width_ratios=[1.5, 1,1]) + if np.isnan(size_diff_bigger): + continue + size_diffs_winner.append(size_diff_bigger) + size_diffs_loser.append(size_diff_smaller) + size_chirps_winner.append(chirp_winner) + size_chirps_loser.append(chirp_loser) + + + embed() + size_winner_pearsonr = pearsonr(size_diffs_winner, size_chirps_winner ) + size_loser_pearsonr = pearsonr(size_diffs_loser, size_chirps_loser ) + + fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=( + 22*ps.cm, 12*ps.cm), width_ratios=[1.5, 1, 1], sharey=True) plt.subplots_adjust(left=0.098, right=0.945, top=0.94, wspace=0.343) scatterwinner = 1.15 scatterloser = 1.85 @@ -189,17 +276,19 @@ def main(datapath: str): ps.set_boxplot_color(bplot1, colors1) colors1 = ps.orange ps.set_boxplot_color(bplot2, colors1) - ax2.scatter(size_diffs, size_chirps_diffs, color='r') - ax2.set_xlabel('Size difference [mm]') + ax2.scatter(size_diffs_winner, size_chirps_winner, color=ps.red) + ax2.scatter(size_diffs_loser, size_chirps_loser, color=ps.orange) + + ax2.set_xlabel('Size difference [cm]') ax2.set_ylabel('Chirps difference [n]') - #ax3.scatter(freq_diffs, size_chirps_diffs, color='r') - # ax3.scatter(freq_diffs, freq_chirps_diffs, color='r') + ax3.scatter(freq_diffs_higher, freq_chirps_winner, color=ps.red) + ax3.scatter(freq_diffs_lower, freq_chirps_loser, color=ps.orange) + ax3.set_xlabel('Frequency difference [Hz]') ax3.set_yticklabels([]) - ax3.set - - #plt.savefig('../poster/figs/chirps_winner_loser.pdf') + # pearson r + plt.savefig('../poster/figs/chirps_winner_loser.pdf') plt.show() diff --git a/poster/figs/chirps_winner_loser.pdf b/poster/figs/chirps_winner_loser.pdf index 723e444d4e69130bb8c0dbbaa15ccc4ba9e8b126..dce23ace3902aebdfdc7058c46643b2ec626f2c0 100644 GIT binary patch delta 4887 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 OD0mW7R`!sw9`t{F<&Cib delta 4913 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