546 lines
21 KiB
Python
546 lines
21 KiB
Python
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.dates as mdates
|
|
import matplotlib.gridspec as gridspec
|
|
|
|
from IPython import embed
|
|
|
|
|
|
# fill aifl with the IDs
|
|
def fill_aifl(id0, id1, aifl, Ch, Ch_connect, matrix_fish_counter, time, frequency, identity, faifl):
|
|
""" his function checks where to adds the two identities to the aifl
|
|
|
|
3 cases:
|
|
1: both ids do not exist in aifl - new fish and both ids are added to that fish number
|
|
2: both ids already exist in aifl - check whether the ids exist in the same fish number -- old fish
|
|
- if not the same number the traces of both fish numbers are plotted and than
|
|
by input of the person either but together as on fish number or added to the faifl
|
|
3: one of the ids exist in aifl - add the other id to the same fish number
|
|
|
|
Parameters
|
|
----------
|
|
id0: int
|
|
ID of the first trace
|
|
id1: int
|
|
ID of the second trace
|
|
aifl: 3-D array
|
|
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
|
|
Ch: int
|
|
first channel
|
|
Ch_connect: int
|
|
channel of id1 and to which we connect
|
|
matrix_fish_counter: int
|
|
counter where the new fish should be registered
|
|
time: 2-D array
|
|
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
|
|
frequency: 2-D array
|
|
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
|
|
identity: 2-D array
|
|
loaded ident array; 1_D: channel; 2_D: identities [int]
|
|
faifl: 2-D array
|
|
false all identity fish list; 1_D: number of how many false enteries in the aifl exist
|
|
2_D: channels and fish number that are falsely connected;
|
|
4 columns: Ch, fishN0, Ch_connect, fishN1
|
|
|
|
Returns
|
|
-------
|
|
matrix_fish_counter: int
|
|
updated counter
|
|
aifl: 3-D array
|
|
updated aifl
|
|
faifl 2-D array
|
|
updated faifl
|
|
"""
|
|
|
|
# fish number
|
|
fishN0 = np.where(aifl[Ch][:][:] == id0)
|
|
fishN1 = np.where(aifl[Ch_connect][:][:] == id1)
|
|
|
|
# when none of the IDs existes -- new fish
|
|
if aifl[Ch][fishN0].size == 0 and aifl[Ch_connect][fishN1].size == 0:
|
|
aifl[Ch][matrix_fish_counter][0] = id0
|
|
aifl[Ch_connect][matrix_fish_counter][0] = id1
|
|
matrix_fish_counter += 1
|
|
print('new fish - ', matrix_fish_counter-1)
|
|
|
|
# what happens when both IDs already exist in the channels
|
|
elif aifl[Ch][fishN0].size != 0 and aifl[Ch_connect][fishN1].size != 0:
|
|
try:
|
|
# both IDs are already together as one fish
|
|
if fishN0[0] == fishN1[0]:
|
|
print('old fish')
|
|
# the IDs are in two different fish, we have to check is the fish should be merged
|
|
# plotting to identify by eye
|
|
# then input if the traces should be merged:
|
|
# yes/no/false --- if the merge before was already false
|
|
else:
|
|
print('confused fish', fishN0[0][0], fishN1[0][0])
|
|
|
|
a1 = aifl[:, fishN0[0], :]
|
|
a2 = aifl[:, fishN1[0], :]
|
|
|
|
for i in range(a1.shape[0]):
|
|
if a2[i, 0, ~np.isnan(a2[i, 0, :])].size != 0:
|
|
append_counter = 1
|
|
for j in range(a2[i, 0, ~np.isnan(a2[i, 0, :])].size):
|
|
print(a2[i][0][j])
|
|
nan_pos = np.where(a1[i, 0, ~np.isnan(a1[i, 0, :])])[0]
|
|
if nan_pos.size != 0:
|
|
aifl[i, fishN0[0], nan_pos[-1] + append_counter] = a2[i, 0, j]
|
|
append_counter += 1
|
|
else:
|
|
aifl[i, fishN0[0], 0] = a2[i, 0, j]
|
|
aifl[:, fishN1[0], :] = np.nan
|
|
|
|
# plot_confused_fish(time, frequency, identity, aifl, id0, id1, Ch, Ch_connect)
|
|
# go_signal = input('Are the traces matching? [y/n/f]')
|
|
#
|
|
# # if the merge before was already false and the fish_number is already in the faifl
|
|
# if np.any(faifl[:, [1, 3]] == fishN0[0][0]) or np.any(faifl[:, [1, 3]] == fishN1[0][0]):
|
|
# print('Traces are not matching')
|
|
# faifl = np.append(faifl, [[Ch, fishN0[0][0], Ch_connect, fishN1[0][0]]], axis=0)
|
|
# # go_signal = yes: merge the two fish to one
|
|
# elif go_signal == 'y':
|
|
# a1 = aifl[:, fishN0[0], :]
|
|
# a2 = aifl[:, fishN1[0], :]
|
|
#
|
|
# for i in range(a1.shape[0]):
|
|
# if a2[i, 0, ~np.isnan(a2[i, 0, :])].size != 0:
|
|
# append_counter = 1
|
|
# for j in range(a2[i, 0, ~np.isnan(a2[i, 0, :])].size):
|
|
# print(a2[i][0][j])
|
|
# nan_pos = np.where(a1[i, 0, ~np.isnan(a1[i, 0, :])])[0]
|
|
# if nan_pos.size != 0:
|
|
# aifl[i, fishN0[0], nan_pos[-1] + append_counter] = a2[i, 0, j]
|
|
# append_counter += 1
|
|
# else:
|
|
# aifl[i, fishN0[0], 0] = a2[i, 0, j]
|
|
# aifl[:, fishN1[0], :] = np.nan
|
|
#
|
|
# # go_signal = false: do not merge and put the fish_number into the faifl
|
|
# elif go_signal == 'f':
|
|
# faifl = np.append(faifl, [[Ch, fishN0[0][0], Ch_connect, fishN1[0][0]]], axis=0)
|
|
#
|
|
# # go_signal = everything else/no: no merge
|
|
# else:
|
|
# print('no merge')
|
|
except:
|
|
embed()
|
|
quit()
|
|
|
|
# if one of the fish does exist but the other one not:
|
|
# if fish0 exists assign fish1 the same fish_number
|
|
elif aifl[Ch][fishN0].size != 0:
|
|
aifl = add_id_to_aifl(aifl, Ch_connect, id1, fishN0)
|
|
|
|
# if fish1 exists assign fish0 the same fish_number
|
|
elif aifl[Ch_connect][fishN1].size != 0:
|
|
aifl = add_id_to_aifl(aifl, Ch, id0, fishN1)
|
|
|
|
return matrix_fish_counter, aifl, faifl
|
|
|
|
|
|
def add_id_to_aifl(aifl, Ch, ID, fishN):
|
|
""" adds the ID to the fishN in aifl
|
|
|
|
Parameters
|
|
----------
|
|
aifl: 3-D array
|
|
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
|
|
Ch: int
|
|
Channel
|
|
ID: int
|
|
the fishID which is added to aifl
|
|
fishN: int
|
|
the fish number to which we add the ID
|
|
|
|
Returns
|
|
-------
|
|
aifl: 3-D array
|
|
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
|
|
with the new ID at the fishN
|
|
"""
|
|
|
|
nan_pos = np.where(aifl[Ch][fishN[0]][~np.isnan(aifl[Ch][fishN[0]])])[0]
|
|
if nan_pos.size != 0:
|
|
aifl[Ch][fishN[0][0]][nan_pos[-1] + 1] = ID
|
|
else:
|
|
aifl[Ch][fishN[0][0]][0] = ID
|
|
return aifl
|
|
|
|
|
|
def plot_confused_fish(time, frequency, identity, aifl, id0, id1, Ch, Ch_next):
|
|
""" plots the two traces which should be connected but already exists in two different fish numbers in the aifl
|
|
it plots all the traces of this channel and the next of both fish numbers
|
|
|
|
plot both traces in question: fish0 -- red; fish1 -- blue
|
|
plot the existing traces of the fish_numbers in question
|
|
plot traces of fish0 in channel and channel+1 in grey and black
|
|
plot traces of fish1 in channel and channel+1 in green and yellow
|
|
|
|
Parameters
|
|
----------
|
|
time: 2-D array
|
|
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
|
|
frequency: 2-D array
|
|
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
|
|
identity: 2-D array
|
|
loaded ident array; 1_D: channel; 2_D: identities [int]
|
|
aifl: 3-D array
|
|
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
|
|
id0: int
|
|
identity of the first trace
|
|
id1: int
|
|
identity of the second trace
|
|
Ch: int
|
|
current channel
|
|
Ch_next: int
|
|
next channel to which we connect
|
|
|
|
Returns
|
|
-------
|
|
nothing
|
|
|
|
"""
|
|
# parameter
|
|
t0 = time[Ch][identity[Ch] == id0]
|
|
f0 = frequency[Ch][identity[Ch] == id0]
|
|
t1 = time[Ch_next][identity[Ch_next] == id1]
|
|
f1 = frequency[Ch_next][identity[Ch_next] == id1]
|
|
fishN0 = np.where(aifl[Ch][:][:] == id0)
|
|
fishN1 = np.where(aifl[Ch_next][:][:] == id1)
|
|
|
|
# ToDo: ich hab das == True entfernt, wenns nicht mehr läuft zurück ändern
|
|
# ~np.isnan(aifl[connect_channel][where_id1[0]]) == True
|
|
for plotidx0 in range(len(np.where(~np.isnan(aifl[Ch][fishN0[0]]))[1])):
|
|
plt.plot(time[Ch][identity[Ch] == aifl[Ch][fishN0[0][0]][plotidx0]],
|
|
frequency[Ch][identity[Ch] == aifl[Ch][fishN0[0][0]][plotidx0]],
|
|
'grey', LineWidth=6, alpha=0.5)
|
|
|
|
for plotidx00 in range(len(np.where(~np.isnan(aifl[Ch_next][fishN0[0]]))[1])):
|
|
plt.plot(time[Ch_next][identity[Ch_next] == aifl[Ch_next][fishN0[0][0]][plotidx00]],
|
|
frequency[Ch_next][
|
|
identity[Ch_next] == aifl[Ch_next][fishN0[0][0]][plotidx00]],
|
|
'black', LineWidth=5, alpha=0.5)
|
|
|
|
for plotidx1 in range(len(np.where(~np.isnan(aifl[Ch_next][fishN1[0]]))[1])):
|
|
plt.plot(time[Ch_next][identity[Ch_next] == aifl[Ch_next][fishN1[0][0]][plotidx1]],
|
|
frequency[Ch_next][
|
|
identity[Ch_next] == aifl[Ch_next][fishN1[0][0]][plotidx1]],
|
|
'green', LineWidth=4, alpha=0.5)
|
|
|
|
for plotidx11 in range(len(np.where(~np.isnan(aifl[Ch][fishN1[0]]))[1])):
|
|
plt.plot(time[Ch][identity[Ch] == aifl[Ch][fishN1[0][0]][plotidx11]],
|
|
frequency[Ch][identity[Ch] == aifl[Ch][fishN1[0][0]][plotidx11]],
|
|
'yellow', LineWidth=3, alpha=0.5)
|
|
|
|
plt.plot(t0, f0, 'red', LineWidth=2)
|
|
plt.plot(t1, f1, 'blue', LineWidth=1)
|
|
plt.title('ch {}: fish {}; ch {}: fish {}'.format(Ch, fishN0[0][0], Ch_next, fishN1[0][0]))
|
|
plt.show()
|
|
|
|
|
|
def plot_together(time, frequency, identity, aifl, fishN, farbe):
|
|
""" plots all the frequency-time traces of all identities of one fish
|
|
|
|
Parameters
|
|
----------
|
|
time: 2-D array
|
|
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
|
|
frequency: 2-D array
|
|
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
|
|
identity: 2-D array
|
|
loaded ident array; 1_D: channel; 2_D: identities [int]
|
|
aifl: 3-D array
|
|
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
|
|
fishN: int
|
|
number of the fish for aifl
|
|
farbe: str
|
|
hex color for the plot
|
|
|
|
Returns
|
|
-------
|
|
nothing
|
|
"""
|
|
|
|
fig = plt.figure(figsize=(16, 14))
|
|
fig.suptitle('fish {}'.format(fishN))
|
|
for channel_idx in range(16):
|
|
fish1 = aifl[channel_idx, fishN, ~np.isnan(aifl[channel_idx, fishN])]
|
|
r1 = len(fish1)
|
|
print(fish1)
|
|
for len_idx1 in range(r1):
|
|
plt.plot(time[channel_idx][identity[channel_idx] == fish1[len_idx1]],
|
|
frequency[channel_idx][identity[channel_idx] == fish1[len_idx1]],
|
|
Linewidth=1, label=str(channel_idx) + ',' + str(fish1[len_idx1]), color=farbe)
|
|
# plt.subplots_adjust(bottom=0.2)
|
|
ax = plt.gca()
|
|
legend_without_duplicate_labels(fig, ax)
|
|
plt.show()
|
|
|
|
return ax
|
|
|
|
|
|
def plot_all_channels(time, frequency, identity, aifl, fishN1, fishN2=None):
|
|
""" plots all the traces of each channel in a different subfigures
|
|
|
|
Parameters
|
|
----------
|
|
time: 2-D array
|
|
loaded time array; 1_D: channel; 2_D: arbitrary time points [int]
|
|
frequency: 2-D array
|
|
loaded frequency array; 1_D: channel; 2_D: frequencies [Hz]
|
|
identity: 2-D array
|
|
loaded ident array; 1_D: channel; 2_D: identities [int]
|
|
aifl: 3-D array
|
|
all identity fish list; 1_D: channel; 2_D: fish number; 3_D: fish identities
|
|
fishN1: int
|
|
fish number of the first fish
|
|
fishN2: int; optional
|
|
fish number of the second fish
|
|
|
|
Returns
|
|
-------
|
|
nothing
|
|
"""
|
|
|
|
xcounter = 0
|
|
ycounter = 0
|
|
|
|
fig1, axs1 = plt.subplots(nrows=4, ncols=4, sharex=True, sharey=True, figsize=(16, 14))
|
|
fig1.suptitle('fish {}; fish {}'.format(fishN1, fishN2))
|
|
for channel_idx in range(16):
|
|
fish1 = aifl[channel_idx, fishN1, ~np.isnan(aifl[channel_idx, fishN1])]
|
|
r1 = len(fish1)
|
|
print(fish1)
|
|
for len_idx1 in range(r1):
|
|
axs1[ycounter, xcounter].plot(time[channel_idx][identity[channel_idx] == fish1[len_idx1]],
|
|
frequency[channel_idx][identity[channel_idx] == fish1[len_idx1]],
|
|
'gray', Linewidth=3)
|
|
# if fishN2 is given
|
|
if fishN2 is not None:
|
|
fish2 = aifl[channel_idx, fishN2, ~np.isnan(aifl[channel_idx, fishN2])]
|
|
r2 = len(fish2)
|
|
for len_idx2 in range(r2):
|
|
axs1[ycounter, xcounter].plot(time[channel_idx][identity[channel_idx] == fish2[len_idx2]],
|
|
frequency[channel_idx][identity[channel_idx] == fish2[len_idx2]],
|
|
'blue', Linewidth=1)
|
|
if xcounter == 3:
|
|
xcounter = 0
|
|
ycounter = ycounter + 1
|
|
else:
|
|
xcounter = xcounter + 1
|
|
plt.show()
|
|
|
|
|
|
def legend_without_duplicate_labels(fig, ax):
|
|
""" creats a legend without duplicated labels
|
|
|
|
Parameters
|
|
----------
|
|
fig: figure handle
|
|
ax: ax handle
|
|
|
|
"""
|
|
handles, labels = ax.get_legend_handles_labels()
|
|
unique = [(h, l) for lwdl_idx, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:lwdl_idx]]
|
|
ax.legend(*zip(*unique), bbox_to_anchor=(1, 0.4), loc="center right", bbox_transform=fig.transFigure, ncol=1)
|
|
|
|
|
|
def running_3binsizes(ipp, sampling_rate):
|
|
"""
|
|
|
|
Parameters
|
|
----------
|
|
ipp: 2-D array
|
|
interpolated power pancake; power of the signal over time for each channel
|
|
1_D: channel; 2_D: power of the signal over time
|
|
sampling_rate: int
|
|
sampling rate of the recordings
|
|
|
|
Returns
|
|
-------
|
|
run_mean: 2-D array
|
|
running mean with different bin sizes,
|
|
first dimension: mean, second: bin size (from the running function)
|
|
run_std: 2-D array
|
|
running std with different bin sizes,
|
|
first dimension: std, second: bin size (from the running function, same bin size as mean)
|
|
|
|
"""
|
|
|
|
# lists
|
|
running_mean = []
|
|
running_std = []
|
|
|
|
# max power in which channel of ipp
|
|
max_ch = np.argmax(ipp, axis=1)
|
|
|
|
# bin sizes
|
|
bin1 = int(np.floor(15 * 60 / sampling_rate))
|
|
bin2 = int(np.floor(30 * 60 / sampling_rate))
|
|
bin3 = int(np.floor(60 * 60 / sampling_rate))
|
|
|
|
# steps with steps 1/2 of bin size
|
|
steps1 = np.arange(0, int(len(max_ch) - bin1), 7.5 * 60)
|
|
steps2 = np.arange(0, int(len(max_ch) - bin2), 15 * 60)
|
|
steps3 = np.arange(0, int(len(max_ch) - bin2), 30 * 60)
|
|
|
|
# make running mean, std and sem
|
|
for bins, step in zip([bin1, bin2, bin3], [steps1, steps2, steps3]):
|
|
bin_mean = np.full([len(max_ch)], np.nan)
|
|
bin_std = np.full([len(max_ch)], np.nan)
|
|
|
|
# for i in range(int(len(max_ch) - bins)):
|
|
for i in step:
|
|
i = int(i)
|
|
bin_mean[int(i + np.floor(bins / 2))] = np.mean(max_ch[i:bins + i])
|
|
bin_std[int(i + np.floor(bins / 2))] = np.std(max_ch[i:bins + i])
|
|
|
|
running_mean.append(bin_mean)
|
|
running_std.append(bin_std)
|
|
|
|
return running_mean, running_std
|
|
|
|
|
|
def running_variablebinsize(ipp, sampling_rate):
|
|
''' calculates the running mean and running std of the interpolated power pancake
|
|
with two different bin sizes and a step size half of the bin size
|
|
|
|
Parameters
|
|
----------
|
|
ipp: 2-D array
|
|
interpolated power pancake; power of the signal over time for each channel
|
|
1_D: channel; 2_D: power of the signal over time
|
|
sampling_rate: int
|
|
sampling rate of the recordings
|
|
|
|
Returns
|
|
-------
|
|
running_mean: 2-D array
|
|
running mean over the time axis with two different bin sizes and step sizes, which are also
|
|
dependent on the length of the time trace;
|
|
1_D: different bin size [2]; 2_D: MEAN, (with steps half of the bin size)
|
|
running_std: 2-D array
|
|
running std over the time axis with two different bin sizes and step sizes, which are also
|
|
dependent on the length of the time trace;
|
|
1_D: different bin size [2]; 2_D: STD, (with steps half of the bin size)
|
|
|
|
'''
|
|
|
|
# lists
|
|
running_mean = []
|
|
running_std = []
|
|
|
|
# max power in which channel of ipp
|
|
max_ch = np.argmax(ipp, axis=1)
|
|
|
|
# calculate bin sizes
|
|
if len(ipp) <= 1800 / sampling_rate: # all time traces < 30 min
|
|
bin1 = int(np.floor(60 / sampling_rate))
|
|
bin2 = int(np.floor(2 * 60 / sampling_rate))
|
|
steps1 = np.arange(0, int(len(max_ch) - bin1), 0.5 * 60)
|
|
steps2 = np.arange(0, int(len(max_ch) - bin2), 1 * 60)
|
|
|
|
elif len(ipp) <= 14400 / sampling_rate: # all time traces < 4 h
|
|
bin1 = int(np.floor(10 * 60 / sampling_rate))
|
|
bin2 = int(np.floor(20 * 60 / sampling_rate))
|
|
steps1 = np.arange(0, int(len(max_ch) - bin1), 5 * 60)
|
|
steps2 = np.arange(0, int(len(max_ch) - bin2), 10 * 60)
|
|
|
|
elif len(ipp) > 14400 / sampling_rate: # all time traces > 4 h
|
|
bin1 = int(np.floor(60 * 60 / sampling_rate))
|
|
bin2 = int(np.floor(180 * 60 / sampling_rate))
|
|
steps1 = np.arange(0, int(len(max_ch) - bin1), 30 * 60)
|
|
steps2 = np.arange(0, int(len(max_ch) - bin2), 90 * 60)
|
|
|
|
# make running mean, std and sem
|
|
for bins, step in zip([bin1, bin2], [steps1, steps2]):
|
|
bin_mean = np.full([len(max_ch)], np.nan)
|
|
bin_std = np.full([len(max_ch)], np.nan)
|
|
|
|
# for i in range(int(len(max_ch) - bins)):
|
|
for i in step:
|
|
i = int(i)
|
|
bin_mean[int(i + np.floor(bins / 2))] = np.mean(max_ch[i:bins + i])
|
|
bin_std[int(i + np.floor(bins / 2))] = np.std(max_ch[i:bins + i])
|
|
|
|
running_mean.append(bin_mean)
|
|
running_std.append(bin_std)
|
|
running_mean = np.array(running_mean)
|
|
running_std = np.array(running_std)
|
|
|
|
return running_mean, running_std
|
|
|
|
|
|
def plot_running(x, run_mean, run_std, threshold, fish, farbe, fs, fs_ticks, lw):
|
|
"""
|
|
|
|
Parameters
|
|
----------
|
|
x: 1-D array
|
|
x axis points in date time format
|
|
run_mean: 2-D array
|
|
running mean with different bin sizes,
|
|
first dimension: mean, second: bin size (from the running function)
|
|
run_std: 2-D array
|
|
running std with different bin sizes,
|
|
first dimension: std, second: bin size (from the running function, same bin size as mean)
|
|
threshold: 1-D array
|
|
threshold for the activity phases dependent on the run mean,
|
|
length of array same as how many bin sizes where calculated
|
|
fish: int
|
|
title for the figure
|
|
farbe: 1-D list
|
|
list with all available colors from the matplotlib.colors in hex-color code
|
|
fs: int; fontsize
|
|
fs_ticks: int; fontsize of ticks
|
|
lw: int; line width
|
|
|
|
Returns
|
|
-------
|
|
|
|
"""
|
|
|
|
fig = plt.figure(figsize=(16, 14))
|
|
spec = gridspec.GridSpec(ncols=2, nrows=2, figure=fig)
|
|
ax1 = fig.add_subplot(spec[0, 0])
|
|
ax2 = fig.add_subplot(spec[0, 1])
|
|
ax3 = fig.add_subplot(spec[1, 0])
|
|
ax4 = fig.add_subplot(spec[1, 1])
|
|
|
|
plt.suptitle('fish {}'.format(fish), fontsize=fs + 2)
|
|
ax_cntr = 0
|
|
|
|
for ax in [ax1, ax2, ax3]:
|
|
non_nan = np.arange(len(run_mean[ax_cntr]))[~np.isnan(run_mean[ax_cntr])]
|
|
|
|
ax.plot(x[fish][non_nan], run_mean[ax_cntr][non_nan], '.', color=farbe[ax_cntr + 4])
|
|
ax.fill_between(x[fish][non_nan], run_mean[ax_cntr][non_nan] + run_std[ax_cntr][non_nan],
|
|
run_mean[ax_cntr][non_nan] - run_std[ax_cntr][non_nan],
|
|
facecolor=farbe[ax_cntr + 4], alpha=0.5)
|
|
|
|
ax4.plot(x[fish][non_nan], run_std[ax_cntr][non_nan], color=farbe[ax_cntr + 4],
|
|
label=threshold[ax_cntr])
|
|
|
|
ax4.plot([x[fish][non_nan][0], x[fish][non_nan][-1]],
|
|
[threshold[ax_cntr], threshold[ax_cntr]],
|
|
color=farbe[ax_cntr + 4])
|
|
ax_cntr += 1
|
|
|
|
ax.set_ylim([0, 15])
|
|
ax.invert_yaxis()
|
|
|
|
for ax in [ax1, ax2, ax3, ax4]:
|
|
ax.tick_params(width=lw - 2)
|
|
ax.tick_params(axis='both', which='major', labelsize=fs_ticks)
|
|
ax.xaxis_date()
|
|
date_format = mdates.DateFormatter('%H:%M')
|
|
ax.xaxis.set_major_formatter(date_format)
|
|
fig.autofmt_xdate()
|
|
|
|
ax1.set_xlabel('time [h]', fontsize=fs)
|
|
ax1.set_ylabel('channel', fontsize=fs)
|
|
|
|
plt.legend()
|