From b0447b8ab319257019927230b143f1b43b761e0f Mon Sep 17 00:00:00 2001 From: weygoldt <88969563+weygoldt@users.noreply.github.com> Date: Thu, 26 Jan 2023 12:45:14 +0100 Subject: [PATCH] new introplot --- code/plot_introduction_specs.py | 103 +++---- code/plot_kdes.py | 495 ++++++++++++++++++-------------- poster/figs/introplot.pdf | Bin 25267 -> 26016 bytes 3 files changed, 328 insertions(+), 270 deletions(-) diff --git a/code/plot_introduction_specs.py b/code/plot_introduction_specs.py index 20fb562..d91420d 100644 --- a/code/plot_introduction_specs.py +++ b/code/plot_introduction_specs.py @@ -17,7 +17,7 @@ def main(): data = LoadData(datapath) # good chirp times for data: 2022-06-02-10_00 - window_start_seconds = 3 * 60 * 60 + 6 * 60 + 43.5 + 9 + 6.25 + window_start_seconds = 3 * 60 * 60 + 6 * 60 + 43.5 + 9 + 6.24 window_start_index = window_start_seconds * data.raw_rate window_duration_seconds = 0.2 window_duration_index = window_duration_seconds * data.raw_rate @@ -27,8 +27,8 @@ def main(): raw = data.raw[window_start_index:window_start_index + window_duration_index, 10] - fig, (ax1, ax2, ax3) = plt.subplots( - 3, 1, figsize=(12 * ps.cm, 10*ps.cm), sharex=True, sharey=True) + fig, ax = plt.subplots( + 1, 1, figsize=(14 * ps.cm, 6*ps.cm), sharex=True, sharey=True) # plot instantaneous frequency filtered1 = bandpass_filter( @@ -41,13 +41,14 @@ def main(): freqtime2, freq2 = instantaneous_frequency( filtered2, data.raw_rate, smoothing_window=3) - ax1.plot(freqtime1*timescaler, freq1, color=ps.red, - lw=2, label=f"fish 1, {np.median(freq1):.0f} Hz") - ax1.plot(freqtime2*timescaler, freq2, color=ps.orange, - lw=2, label=f"fish 2, {np.median(freq2):.0f} Hz") - ax1.legend(bbox_to_anchor=(0, 1.02, 1, 0.2), loc="lower center", - mode="normal", borderaxespad=0, ncol=2) - ps.hide_xax(ax1) + ax.plot(freqtime1*timescaler, freq1, color=ps.gblue1, + lw=2, label="fish 1") + ax.plot(freqtime2*timescaler, freq2, color=ps.gblue2, + lw=2, label="fish 2") + ax.legend(bbox_to_anchor=(0, 1.02, 1, 0.2), loc="lower center", + mode="normal", borderaxespad=0, ncol=2) + # ax.legend(bbox_to_anchor=(1.04, 1), borderaxespad=0) + # # ps.hide_xax(ax1) # plot fine spectrogram spec_power, spec_freqs, spec_times = spectrogram( @@ -57,11 +58,11 @@ def main(): overlap_frac=0.2, ) - ylims = [300, 1200] + ylims = [300, 1300] fmask = np.zeros(spec_freqs.shape, dtype=bool) fmask[(spec_freqs > ylims[0]) & (spec_freqs < ylims[1])] = True - ax2.imshow( + ax.imshow( decibel(spec_power[fmask, :]), extent=[ spec_times[0]*timescaler, @@ -73,45 +74,47 @@ def main(): origin="lower", interpolation="gaussian", alpha=1, + vmin=-100, + vmax=-80, ) - ps.hide_xax(ax2) - - # plot coarse spectrogram - spec_power, spec_freqs, spec_times = spectrogram( - raw, - ratetime=data.raw_rate, - freq_resolution=10, - overlap_frac=0.3, - ) - fmask = np.zeros(spec_freqs.shape, dtype=bool) - fmask[(spec_freqs > ylims[0]) & (spec_freqs < ylims[1])] = True - ax3.imshow( - decibel(spec_power[fmask, :]), - extent=[ - spec_times[0]*timescaler, - spec_times[-1]*timescaler, - spec_freqs[fmask][0], - spec_freqs[fmask][-1], - ], - aspect="auto", - origin="lower", - interpolation="gaussian", - alpha=1, - ) - # ps.hide_xax(ax3) - - ax3.set_xlabel("time [ms]") - ax2.set_ylabel("frequency [Hz]") - - ax1.set_yticks(np.arange(400, 1201, 400)) - ax1.spines.left.set_bounds((400, 1200)) - ax2.set_yticks(np.arange(400, 1201, 400)) - ax2.spines.left.set_bounds((400, 1200)) - ax3.set_yticks(np.arange(400, 1201, 400)) - ax3.spines.left.set_bounds((400, 1200)) - - plt.subplots_adjust(left=0.17, right=0.98, top=0.9, - bottom=0.14, hspace=0.35) + # ps.hide_xax(ax2) + + # # plot coarse spectrogram + # spec_power, spec_freqs, spec_times = spectrogram( + # raw, + # ratetime=data.raw_rate, + # freq_resolution=10, + # overlap_frac=0.3, + # ) + # fmask = np.zeros(spec_freqs.shape, dtype=bool) + # fmask[(spec_freqs > ylims[0]) & (spec_freqs < ylims[1])] = True + # ax3.imshow( + # decibel(spec_power[fmask, :]), + # extent=[ + # spec_times[0]*timescaler, + # spec_times[-1]*timescaler, + # spec_freqs[fmask][0], + # spec_freqs[fmask][-1], + # ], + # aspect="auto", + # origin="lower", + # interpolation="gaussian", + # alpha=1, + # ) + # # ps.hide_xax(ax3) + + ax.set_xlabel("time [ms]") + ax.set_ylabel("frequency [Hz]") + + # ax.set_yticks(np.arange(400, 1201, 400)) + # ax.spines.left.set_bounds((400, 1200)) + # ax2.set_yticks(np.arange(400, 1201, 400)) + # ax2.spines.left.set_bounds((400, 1200)) + # ax3.set_yticks(np.arange(400, 1201, 400)) + # ax3.spines.left.set_bounds((400, 1200)) + + plt.subplots_adjust(left=0.17, right=0.98, top=0.87, + bottom=0.24, hspace=0.35) plt.savefig('../poster/figs/introplot.pdf') plt.show() diff --git a/code/plot_kdes.py b/code/plot_kdes.py index 5fd9cad..d33279a 100644 --- a/code/plot_kdes.py +++ b/code/plot_kdes.py @@ -1,18 +1,18 @@ -from extract_chirps import get_valid_datasets -import os - -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt -from tqdm import tqdm -from IPython import embed -from pandas import read_csv -from modules.logger import makeLogger -from modules.datahandling import flatten, causal_kde1d, acausal_kde1d +from modules.plotstyle import PlotStyle from modules.behaviour_handling import ( Behavior, correct_chasing_events, center_chirps) -from modules.plotstyle import PlotStyle +from modules.datahandling import flatten, causal_kde1d, acausal_kde1d +from modules.logger import makeLogger +from pandas import read_csv +from IPython import embed +from tqdm import tqdm +import matplotlib.pyplot as plt +import pandas as pd +import numpy as np +import os +from extract_chirps import get_valid_datasets + logger = makeLogger(__name__) ps = PlotStyle() @@ -23,16 +23,16 @@ def bootstrap(data, nresamples, kde_time, kernel_width, event_times, time_before bootstrapped_kdes = [] data = data[data <= 3*60*60] # only night time - # diff_data = np.diff(np.sort(data), prepend=0) + diff_data = np.diff(np.sort(data), prepend=0) # if len(data) != 0: # mean_chirprate = (len(data) - 1) / (data[-1] - data[0]) for i in tqdm(range(nresamples)): - # np.random.shuffle(diff_data) + np.random.shuffle(diff_data) - # bootstrapped_data = np.cumsum(diff_data) - bootstrapped_data = data + np.random.randn(len(data)) * 10 + bootstrapped_data = np.cumsum(diff_data) + # bootstrapped_data = data + np.random.randn(len(data)) * 10 bootstrap_data_centered = center_chirps( bootstrapped_data, event_times, time_before, time_after) @@ -40,8 +40,8 @@ def bootstrap(data, nresamples, kde_time, kernel_width, event_times, time_before bootstrapped_kde = acausal_kde1d( bootstrap_data_centered, time=kde_time, width=kernel_width) - # bootstrapped_kdes = list(np.asarray( - # bootstrapped_kdes) / len(event_times)) + bootstrapped_kde = list(np.asarray( + bootstrapped_kde) / len(event_times)) bootstrapped_kdes.append(bootstrapped_kde) @@ -58,20 +58,20 @@ def jackknife(data, nresamples, subsetsize, kde_time, kernel_width, event_times, for i in tqdm(range(nresamples)): - bootstrapped_data = np.random.sample(data, subsetsize, replace=False) + jackknifed_data = np.random.choice(data, subsetsize, replace=False) - bootstrapped_data = np.cumsum(diff_data) + jackknifed_data = np.cumsum(diff_data) - bootstrap_data_centered = center_chirps( - bootstrapped_data, event_times, time_before, time_after) + jackknifed_data_centered = center_chirps( + jackknifed_data, event_times, time_before, time_after) - bootstrapped_kde = acausal_kde1d( - bootstrap_data_centered, time=kde_time, width=kernel_width) + jackknifed_kde = acausal_kde1d( + jackknifed_data_centered, time=kde_time, width=kernel_width) - # bootstrapped_kdes = list(np.asarray( - # bootstrapped_kdes) / len(event_times)) + jackknifed_kde = list(np.asarray( + jackknifed_kde) / len(event_times)) - jackknife_kdes.append(bootstrapped_kde) + jackknife_kdes.append(jackknifed_kde) return jackknife_kdes @@ -102,14 +102,14 @@ def get_chirp_winner_loser(folder_name, Behavior, order_meta_df): def main(dataroot): - foldernames, _ = get_valid_datasets(dataroot) + foldernames, _ = np.asarray(get_valid_datasets(dataroot)) plot_all = True - time_before = 60 - time_after = 60 + time_before = 90 + time_after = 90 dt = 0.001 - kernel_width = 1 + kernel_width = 2 kde_time = np.arange(-time_before, time_after, dt) - nbootstraps = 2 + nbootstraps = 50 meta_path = ( '/').join(foldernames[0].split('/')[:-2]) + '/order_meta.csv' @@ -135,9 +135,19 @@ def main(dataroot): onset_count = 0 offset_count = 0 physical_count = 0 - + # winner_count = 0 + # loser_count = 0 + # winner_onset_chirpcount = 0 + # winner_offset_chirpcount = 0 + # winner_physical_chirpcount = 0 + # loser_onset_chirpcount = 0 + # loser_offset_chirpcount = 0 + # loser_physical_chirpcount = 0 + fig, ax = plt.subplots(1, 2, figsize=( + 14 * ps.cm, 7*ps.cm), sharey=True, sharex=True) # Iterate over all recordings and save chirp- and event-timestamps - for folder in tqdm(foldernames): + good_recs = np.asarray([0, 15]) + for i, folder in tqdm(enumerate(foldernames[good_recs])): foldername = folder.split('/')[-2] # logger.info('Loading data from folder: {}'.format(foldername)) @@ -153,9 +163,10 @@ def main(dataroot): timestamps = timestamps[timestamps < 3*60*60] # only night time winner, loser = get_chirp_winner_loser(folder, bh, meta) - if winner is None: continue + # winner_count += len(winner) + # loser_count += len(loser) onsets = (timestamps[category == 0]) offsets = (timestamps[category == 1]) @@ -179,42 +190,48 @@ def main(dataroot): loser_physicals.append(center_chirps( loser, physicals, time_before, time_after)) + # winner_onset_chirpcount += len(winner_onsets[-1]) + # winner_offset_chirpcount += len(winner_offsets[-1]) + # winner_physical_chirpcount += len(winner_physicals[-1]) + # loser_onset_chirpcount += len(loser_onsets[-1]) + # loser_offset_chirpcount += len(loser_offsets[-1]) + # loser_physical_chirpcount += len(loser_physicals[-1]) # bootstrap # chirps = [winner, winner, winner, loser, loser, loser] - winner_onsets_boot.append(bootstrap( - winner, - nresamples=nbootstraps, - kde_time=kde_time, - kernel_width=kernel_width, - event_times=onsets, - time_before=time_before, - time_after=time_after)) - winner_offsets_boot.append(bootstrap( - winner, - nresamples=nbootstraps, - kde_time=kde_time, - kernel_width=kernel_width, - event_times=offsets, - time_before=time_before, - time_after=time_after)) - winner_physicals_boot.append(bootstrap( - winner, - nresamples=nbootstraps, - kde_time=kde_time, - kernel_width=kernel_width, - event_times=physicals, - time_before=time_before, - time_after=time_after)) - - loser_onsets_boot.append(bootstrap( - loser, - nresamples=nbootstraps, - kde_time=kde_time, - kernel_width=kernel_width, - event_times=onsets, - time_before=time_before, - time_after=time_after)) + # winner_onsets_boot.append(bootstrap( + # winner, + # nresamples=nbootstraps, + # kde_time=kde_time, + # kernel_width=kernel_width, + # event_times=onsets, + # time_before=time_before, + # time_after=time_after)) + # winner_offsets_boot.append(bootstrap( + # winner, + # nresamples=nbootstraps, + # kde_time=kde_time, + # kernel_width=kernel_width, + # event_times=offsets, + # time_before=time_before, + # time_after=time_after)) + # winner_physicals_boot.append(bootstrap( + # winner, + # nresamples=nbootstraps, + # kde_time=kde_time, + # kernel_width=kernel_width, + # event_times=physicals, + # time_before=time_before, + # time_after=time_after)) + + # loser_onsets_boot.append(bootstrap( + # loser, + # nresamples=nbootstraps, + # kde_time=kde_time, + # kernel_width=kernel_width, + # event_times=onsets, + # time_before=time_before, + # time_after=time_after)) loser_offsets_boot.append(bootstrap( loser, nresamples=nbootstraps, @@ -223,61 +240,99 @@ def main(dataroot): event_times=offsets, time_before=time_before, time_after=time_after)) - loser_physicals_boot.append(bootstrap( + # loser_physicals_boot.append(bootstrap( + # loser, + # nresamples=nbootstraps, + # kde_time=kde_time, + # kernel_width=kernel_width, + # event_times=physicals, + # time_before=time_before, + # time_after=time_after)) + + loser_offsets_jackknife = jackknife( loser, nresamples=nbootstraps, + subsetsize=0.5, kde_time=kde_time, kernel_width=kernel_width, - event_times=physicals, + event_times=offsets, time_before=time_before, - time_after=time_after)) + time_after=time_after) if plot_all: - winner_onsets_conv = acausal_kde1d( - winner_onsets[-1], kde_time, kernel_width) - winner_offsets_conv = acausal_kde1d( - winner_offsets[-1], kde_time, kernel_width) - winner_physicals_conv = acausal_kde1d( - winner_physicals[-1], kde_time, kernel_width) + # winner_onsets_conv = acausal_kde1d( + # winner_onsets[-1], kde_time, kernel_width) + # winner_offsets_conv = acausal_kde1d( + # winner_offsets[-1], kde_time, kernel_width) + # winner_physicals_conv = acausal_kde1d( + # winner_physicals[-1], kde_time, kernel_width) - loser_onsets_conv = acausal_kde1d( - loser_onsets[-1], kde_time, kernel_width) + # loser_onsets_conv = acausal_kde1d( + # loser_onsets[-1], kde_time, kernel_width) loser_offsets_conv = acausal_kde1d( loser_offsets[-1], kde_time, kernel_width) - loser_physicals_conv = acausal_kde1d( - loser_physicals[-1], kde_time, kernel_width) - - fig, ax = plt.subplots(2, 3, figsize=( - 21*ps.cm, 10*ps.cm), sharey=True, sharex=True) - ax[0, 0].set_title( - f"{foldername}, onsets {len(onsets)}, offsets {len(offsets)}, physicals {len(physicals)},winner {len(winner)}, looser {len(loser)} , onsets") - ax[0, 0].plot(kde_time, winner_onsets_conv/len(onsets)) - ax[0, 1].plot(kde_time, winner_offsets_conv/len(offsets)) - ax[0, 2].plot(kde_time, winner_physicals_conv/len(physicals)) - ax[1, 0].plot(kde_time, loser_onsets_conv/len(onsets)) - ax[1, 1].plot(kde_time, loser_offsets_conv/len(offsets)) - ax[1, 2].plot(kde_time, loser_physicals_conv/len(physicals)) + # loser_physicals_conv = acausal_kde1d( + # loser_physicals[-1], kde_time, kernel_width) + + ax[i].plot(kde_time, loser_offsets_conv/len(offsets)) + + ax[i].fill_between( + kde_time, + np.percentile(loser_offsets_boot[-1], 5, axis=0), + np.percentile(loser_offsets_boot[-1], 95, axis=0), + color=ps.gray, + alpha=0.5) + + ax[i].plot(kde_time, np.median(loser_offsets_boot[-1], axis=0), + color=ps.black, linewidth=2) + + ax[i].fill_between( + kde_time, + np.percentile(loser_offsets_jackknife, 5, axis=0), + np.percentile(loser_offsets_jackknife, 95, axis=0), + color=ps.blue, + alpha=0.5) + ax[i].plot(kde_time, np.median(loser_offsets_jackknife, axis=0), + color=ps.white, linewidth=2) + + ax[i].set_xlim(-60, 60) + + embed() + + # fig, ax = plt.subplots(2, 3, figsize=( + # 21*ps.cm, 10*ps.cm), sharey=True, sharex=True) + # ax[0, 0].set_title( + # f"{foldername}, onsets {len(onsets)}, offsets {len(offsets)}, physicals {len(physicals)},winner {len(winner)}, looser {len(loser)} , onsets") + # ax[0, 0].plot(kde_time, winner_onsets_conv/len(onsets)) + # ax[0, 1].plot(kde_time, winner_offsets_conv / + # len(offsets)) + # ax[0, 2].plot(kde_time, winner_physicals_conv / + # len(physicals)) + # ax[1, 0].plot(kde_time, loser_onsets_conv/len(onsets)) + # ax[1, 1].plot(kde_time, loser_offsets_conv/len(offsets)) + # ax[1, 2].plot(kde_time, loser_physicals_conv / + # len(physicals)) # # plot bootstrap lines - for kde in winner_onsets_boot[-1]: - ax[0, 0].plot(kde_time, kde/len(onsets), - color='gray') - for kde in winner_offsets_boot[-1]: - ax[0, 1].plot(kde_time, kde/len(offsets), - color='gray') - for kde in winner_physicals_boot[-1]: - ax[0, 2].plot(kde_time, kde/len(physicals), - color='gray') - for kde in loser_onsets_boot[-1]: - ax[1, 0].plot(kde_time, kde/len(onsets), - color='gray') - for kde in loser_offsets_boot[-1]: - ax[1, 1].plot(kde_time, kde/len(offsets), - color='gray') - for kde in loser_physicals_boot[-1]: - ax[1, 2].plot(kde_time, kde/len(physicals), - color='gray') + # for kde in winner_onsets_boot[-1]: + # ax[0, 0].plot(kde_time, kde, + # color='gray') + # for kde in winner_offsets_boot[-1]: + # ax[0, 1].plot(kde_time, kde, + # color='gray') + # for kde in winner_physicals_boot[-1]: + # ax[0, 2].plot(kde_time, kde, + # color='gray') + # for kde in loser_onsets_boot[-1]: + # ax[1, 0].plot(kde_time, kde, + # color='gray') + # for kde in loser_offsets_boot[-1]: + # ax[1, 1].plot(kde_time, kde, + # color='gray') + # for kde in loser_physicals_boot[-1]: + # ax[1, 2].plot(kde_time, kde, + # color='gray') # plot bootstrap percentiles # ax[0, 0].fill_between( @@ -335,79 +390,79 @@ def main(dataroot): # ax[1, 2].plot(kde_time, np.median(loser_physicals_boot[-1], axis=0), # color='black', linewidth=2) - ax[0, 0].set_xlim(-30, 30) - plt.show() - - winner_onsets = np.sort(flatten(winner_onsets)) - winner_offsets = np.sort(flatten(winner_offsets)) - winner_physicals = np.sort(flatten(winner_physicals)) - loser_onsets = np.sort(flatten(loser_onsets)) - loser_offsets = np.sort(flatten(loser_offsets)) - loser_physicals = np.sort(flatten(loser_physicals)) - - winner_onsets_conv = acausal_kde1d( - winner_onsets, kde_time, kernel_width) - winner_offsets_conv = acausal_kde1d( - winner_offsets, kde_time, kernel_width) - winner_physicals_conv = acausal_kde1d( - winner_physicals, kde_time, kernel_width) - loser_onsets_conv = acausal_kde1d( - loser_onsets, kde_time, kernel_width) - loser_offsets_conv = acausal_kde1d( - loser_offsets, kde_time, kernel_width) - loser_physicals_conv = acausal_kde1d( - loser_physicals, kde_time, kernel_width) - - winner_onsets_conv = winner_onsets_conv / onset_count - winner_offsets_conv = winner_offsets_conv / offset_count - winner_physicals_conv = winner_physicals_conv / physical_count - loser_onsets_conv = loser_onsets_conv / onset_count - loser_offsets_conv = loser_offsets_conv / offset_count - loser_physicals_conv = loser_physicals_conv / physical_count - - winner_onsets_boot = np.concatenate( - winner_onsets_boot) - winner_offsets_boot = np.concatenate( - winner_offsets_boot) - winner_physicals_boot = np.concatenate( - winner_physicals_boot) - loser_onsets_boot = np.concatenate( - loser_onsets_boot) - loser_offsets_boot = np.concatenate( - loser_offsets_boot) - loser_physicals_boot = np.concatenate( - loser_physicals_boot) - - percs = [5, 50, 95] - winner_onsets_boot_quarts = np.percentile( - winner_onsets_boot, percs, axis=0) - winner_offsets_boot_quarts = np.percentile( - winner_offsets_boot, percs, axis=0) - winner_physicals_boot_quarts = np.percentile( - winner_physicals_boot, percs, axis=0) - loser_onsets_boot_quarts = np.percentile( - loser_onsets_boot, percs, axis=0) - loser_offsets_boot_quarts = np.percentile( - loser_offsets_boot, percs, axis=0) - loser_physicals_boot_quarts = np.percentile( - loser_physicals_boot, percs, axis=0) - - fig, ax = plt.subplots(2, 3, figsize=( - 21*ps.cm, 10*ps.cm), sharey=True, sharex=True) - - ax[0, 0].plot(kde_time, winner_onsets_conv) - ax[0, 1].plot(kde_time, winner_offsets_conv) - ax[0, 2].plot(kde_time, winner_physicals_conv) - ax[1, 0].plot(kde_time, loser_onsets_conv) - ax[1, 1].plot(kde_time, loser_offsets_conv) - ax[1, 2].plot(kde_time, loser_physicals_conv) - - ax[0, 0].plot(kde_time, winner_onsets_boot_quarts[1], c=ps.black) - ax[0, 1].plot(kde_time, winner_offsets_boot_quarts[1], c=ps.black) - ax[0, 2].plot(kde_time, winner_physicals_boot_quarts[1], c=ps.black) - ax[1, 0].plot(kde_time, loser_onsets_boot_quarts[1], c=ps.black) - ax[1, 1].plot(kde_time, loser_offsets_boot_quarts[1], c=ps.black) - ax[1, 2].plot(kde_time, loser_physicals_boot_quarts[1], c=ps.black) + # ax[0, 0].set_xlim(-30, 30) + plt.show() + + # winner_onsets = np.sort(flatten(winner_onsets)) + # winner_offsets = np.sort(flatten(winner_offsets)) + # winner_physicals = np.sort(flatten(winner_physicals)) + # loser_onsets = np.sort(flatten(loser_onsets)) + # loser_offsets = np.sort(flatten(loser_offsets)) + # loser_physicals = np.sort(flatten(loser_physicals)) + + # winner_onsets_conv = acausal_kde1d( + # winner_onsets, kde_time, kernel_width) + # winner_offsets_conv = acausal_kde1d( + # winner_offsets, kde_time, kernel_width) + # winner_physicals_conv = acausal_kde1d( + # winner_physicals, kde_time, kernel_width) + # loser_onsets_conv = acausal_kde1d( + # loser_onsets, kde_time, kernel_width) + # loser_offsets_conv = acausal_kde1d( + # loser_offsets, kde_time, kernel_width) + # loser_physicals_conv = acausal_kde1d( + # loser_physicals, kde_time, kernel_width) + + # winner_onsets_conv = winner_onsets_conv / onset_count + # winner_offsets_conv = winner_offsets_conv / offset_count + # winner_physicals_conv = winner_physicals_conv / physical_count + # loser_onsets_conv = loser_onsets_conv / onset_count + # loser_offsets_conv = loser_offsets_conv / offset_count + # loser_physicals_conv = loser_physicals_conv / physical_count + + # winner_onsets_boot = np.concatenate( + # winner_onsets_boot) + # winner_offsets_boot = np.concatenate( + # winner_offsets_boot) + # winner_physicals_boot = np.concatenate( + # winner_physicals_boot) + # loser_onsets_boot = np.concatenate( + # loser_onsets_boot) + # loser_offsets_boot = np.concatenate( + # loser_offsets_boot) + # loser_physicals_boot = np.concatenate( + # loser_physicals_boot) + + # percs = [5, 50, 95] + # winner_onsets_boot_quarts = np.percentile( + # winner_onsets_boot, percs, axis=0) + # winner_offsets_boot_quarts = np.percentile( + # winner_offsets_boot, percs, axis=0) + # winner_physicals_boot_quarts = np.percentile( + # winner_physicals_boot, percs, axis=0) + # loser_onsets_boot_quarts = np.percentile( + # loser_onsets_boot, percs, axis=0) + # loser_offsets_boot_quarts = np.percentile( + # loser_offsets_boot, percs, axis=0) + # loser_physicals_boot_quarts = np.percentile( + # loser_physicals_boot, percs, axis=0) + + # fig, ax = plt.subplots(2, 3, figsize=( + # 21*ps.cm, 10*ps.cm), sharey=True, sharex=True) + + # ax[0, 0].plot(kde_time, winner_onsets_conv) + # ax[0, 1].plot(kde_time, winner_offsets_conv) + # ax[0, 2].plot(kde_time, winner_physicals_conv) + # ax[1, 0].plot(kde_time, loser_onsets_conv) + # ax[1, 1].plot(kde_time, loser_offsets_conv) + # ax[1, 2].plot(kde_time, loser_physicals_conv) + + # ax[0, 0].plot(kde_time, winner_onsets_boot_quarts[1], c=ps.black) + # ax[0, 1].plot(kde_time, winner_offsets_boot_quarts[1], c=ps.black) + # ax[0, 2].plot(kde_time, winner_physicals_boot_quarts[1], c=ps.black) + # ax[1, 0].plot(kde_time, loser_onsets_boot_quarts[1], c=ps.black) + # ax[1, 1].plot(kde_time, loser_offsets_boot_quarts[1], c=ps.black) + # ax[1, 2].plot(kde_time, loser_physicals_boot_quarts[1], c=ps.black) # for kde in winner_onsets_boot: # ax[0, 0].plot(kde_time, kde, @@ -428,43 +483,43 @@ def main(dataroot): # ax[1, 2].plot(kde_time, kde, # color='gray') - ax[0, 0].fill_between(kde_time, - winner_onsets_boot_quarts[0], - winner_onsets_boot_quarts[2], - color=ps.gray, - alpha=0.5) - - ax[0, 1].fill_between(kde_time, - winner_offsets_boot_quarts[0], - winner_offsets_boot_quarts[2], - color=ps.gray, - alpha=0.5) - - ax[0, 2].fill_between(kde_time, - loser_physicals_boot_quarts[0], - loser_physicals_boot_quarts[2], - color=ps.gray, - alpha=0.5) - - ax[1, 0].fill_between(kde_time, - loser_onsets_boot_quarts[0], - loser_onsets_boot_quarts[2], - color=ps.gray, - alpha=0.5) - - ax[1, 1].fill_between(kde_time, - loser_offsets_boot_quarts[0], - loser_offsets_boot_quarts[2], - color=ps.gray, - alpha=0.5) - - ax[1, 2].fill_between(kde_time, - loser_physicals_boot_quarts[0], - loser_physicals_boot_quarts[2], - color=ps.gray, - alpha=0.5) - - plt.show() + # ax[0, 0].fill_between(kde_time, + # winner_onsets_boot_quarts[0], + # winner_onsets_boot_quarts[2], + # color=ps.gray, + # alpha=0.5) + + # ax[0, 1].fill_between(kde_time, + # winner_offsets_boot_quarts[0], + # winner_offsets_boot_quarts[2], + # color=ps.gray, + # alpha=0.5) + + # ax[0, 2].fill_between(kde_time, + # loser_physicals_boot_quarts[0], + # loser_physicals_boot_quarts[2], + # color=ps.gray, + # alpha=0.5) + + # ax[1, 0].fill_between(kde_time, + # loser_onsets_boot_quarts[0], + # loser_onsets_boot_quarts[2], + # color=ps.gray, + # alpha=0.5) + + # ax[1, 1].fill_between(kde_time, + # loser_offsets_boot_quarts[0], + # loser_offsets_boot_quarts[2], + # color=ps.gray, + # alpha=0.5) + + # ax[1, 2].fill_between(kde_time, + # loser_physicals_boot_quarts[0], + # loser_physicals_boot_quarts[2], + # color=ps.gray, + # alpha=0.5) + + # plt.show() if __name__ == '__main__': diff --git a/poster/figs/introplot.pdf b/poster/figs/introplot.pdf index 7fef6fa0e33be46b259c1a1c5b07d7c04796a5ca..422e37cec0837208d96850536b2087dbee3ae63b 100644 GIT binary patch delta 17894 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 delta 16167 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 i{ygnpI{#