added gridspec plot layout
This commit is contained in:
parent
ddf7bd545a
commit
9f46b969a5
@ -3,6 +3,7 @@ from dataclasses import dataclass
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.gridspec as gr
|
||||||
from scipy.signal import find_peaks
|
from scipy.signal import find_peaks
|
||||||
from thunderfish.powerspectrum import spectrogram, decibel
|
from thunderfish.powerspectrum import spectrogram, decibel
|
||||||
from sklearn.preprocessing import normalize
|
from sklearn.preprocessing import normalize
|
||||||
@ -13,6 +14,7 @@ from modules.plotstyle import PlotStyle
|
|||||||
from modules.logger import makeLogger
|
from modules.logger import makeLogger
|
||||||
from modules.datahandling import (
|
from modules.datahandling import (
|
||||||
flatten,
|
flatten,
|
||||||
|
norm,
|
||||||
purge_duplicates,
|
purge_duplicates,
|
||||||
group_timestamps,
|
group_timestamps,
|
||||||
instantaneous_frequency,
|
instantaneous_frequency,
|
||||||
@ -42,6 +44,7 @@ class PlotBuffer:
|
|||||||
baseline: np.ndarray
|
baseline: np.ndarray
|
||||||
baseline_envelope: np.ndarray
|
baseline_envelope: np.ndarray
|
||||||
baseline_peaks: np.ndarray
|
baseline_peaks: np.ndarray
|
||||||
|
search_frequency: float
|
||||||
search: np.ndarray
|
search: np.ndarray
|
||||||
search_envelope: np.ndarray
|
search_envelope: np.ndarray
|
||||||
search_peaks: np.ndarray
|
search_peaks: np.ndarray
|
||||||
@ -57,15 +60,21 @@ class PlotBuffer:
|
|||||||
|
|
||||||
# make data for plotting
|
# make data for plotting
|
||||||
|
|
||||||
# # get index of track data in this time window
|
# get index of track data in this time window
|
||||||
# window_idx = np.arange(len(self.data.idx))[
|
window_idx = np.arange(len(self.data.idx))[
|
||||||
# (self.data.ident == self.track_id) & (self.data.time[self.data.idx] >= self.t0) & (
|
(self.data.ident == self.track_id) & (self.data.time[self.data.idx] >= self.t0) & (
|
||||||
# self.data.time[self.data.idx] <= (self.t0 + self.dt))
|
self.data.time[self.data.idx] <= (self.t0 + self.dt))
|
||||||
# ]
|
]
|
||||||
|
|
||||||
# get tracked frequencies and their times
|
# get tracked frequencies and their times
|
||||||
# freq_temp = self.data.freq[window_idx]
|
freq_temp = self.data.freq[window_idx]
|
||||||
# time_temp = self.data.times[window_idx]
|
time_temp = self.data.time[(self.data.time >= self.t0) & (
|
||||||
|
self.data.time <= (self.t0 + self.dt))]
|
||||||
|
|
||||||
|
# remake the band we filtered in
|
||||||
|
q25, q50, q75 = np.percentile(freq_temp, [25, 50, 75])
|
||||||
|
search_upper, search_lower = q50 + self.search_frequency + self.config.minimal_bandwidth / \
|
||||||
|
2, q50 + self.search_frequency - self.config.minimal_bandwidth / 2
|
||||||
|
|
||||||
# get indices on raw data
|
# get indices on raw data
|
||||||
start_idx = self.t0 * self.data.raw_rate
|
start_idx = self.t0 * self.data.raw_rate
|
||||||
@ -75,66 +84,90 @@ class PlotBuffer:
|
|||||||
# get raw data
|
# get raw data
|
||||||
data_oi = self.data.raw[start_idx:stop_idx, self.electrode]
|
data_oi = self.data.raw[start_idx:stop_idx, self.electrode]
|
||||||
|
|
||||||
fig, axs = plt.subplots(
|
self.time = (self.time - self.t0)
|
||||||
7,
|
self.frequency_time = (self.frequency_time - self.t0)
|
||||||
1,
|
chirps = (np.ararray(chirps) - self.t0)
|
||||||
figsize=(20 / 2.54, 12 / 2.54),
|
self.t0 = 0
|
||||||
constrained_layout=True,
|
|
||||||
sharex=True,
|
fig = plt.figure(figsize=(16 / 2.54, 24 / 2.54),
|
||||||
sharey="row",
|
constrained_layout=True)
|
||||||
)
|
|
||||||
|
grid = gr.GridSpec(9, 1, figure=fig, height_ratios=[
|
||||||
|
4, 0.5, 1, 1, 1, 0.5, 1, 1, 1])
|
||||||
|
|
||||||
|
ax0 = fig.add_subplot(grid[0, 0])
|
||||||
|
ax1 = fig.add_subplot(grid[2, 0], sharex=ax0)
|
||||||
|
ax2 = fig.add_subplot(grid[3, 0], sharex=ax0)
|
||||||
|
ax3 = fig.add_subplot(grid[4, 0], sharex=ax0)
|
||||||
|
ax4 = fig.add_subplot(grid[6, 0], sharex=ax0)
|
||||||
|
ax5 = fig.add_subplot(grid[7, 0], sharex=ax0)
|
||||||
|
ax6 = fig.add_subplot(grid[8, 0], sharex=ax0)
|
||||||
|
|
||||||
# plot spectrogram
|
# plot spectrogram
|
||||||
plot_spectrogram(axs[0], data_oi, self.data.raw_rate, self.t0)
|
plot_spectrogram(ax0, data_oi, self.data.raw_rate, self.t0)
|
||||||
|
|
||||||
|
ax0.fill_between(
|
||||||
|
np.arange(self.t0, self.t0 + self.dt, 1 / self.data.raw_rate),
|
||||||
|
q50 - self.config.minimal_bandwidth / 2,
|
||||||
|
q50 + self.config.minimal_bandwidth / 2,
|
||||||
|
color=ps.black,
|
||||||
|
lw=0,
|
||||||
|
alpha=0.2)
|
||||||
|
|
||||||
|
ax0.fill_between(
|
||||||
|
np.arange(self.t0, self.t0 + self.dt, 1 / self.data.raw_rate),
|
||||||
|
search_lower,
|
||||||
|
search_upper,
|
||||||
|
color=ps.black,
|
||||||
|
lw=0,
|
||||||
|
alpha=0.2)
|
||||||
|
|
||||||
for chirp in chirps:
|
for chirp in chirps:
|
||||||
axs[0].scatter(
|
ax0.scatter(
|
||||||
chirp, np.median(self.frequency), c=ps.black, marker="x"
|
chirp, np.median(self.frequency), c=ps.black, marker="x"
|
||||||
)
|
)
|
||||||
|
|
||||||
# plot waveform of filtered signal
|
# plot waveform of filtered signal
|
||||||
axs[1].plot(self.time, self.baseline, c=ps.green)
|
ax1.plot(self.time, norm(self.baseline))
|
||||||
|
|
||||||
# plot waveform of filtered search signal
|
# plot waveform of filtered search signal
|
||||||
axs[2].plot(self.time, self.search)
|
ax2.plot(self.time, norm(self.search))
|
||||||
|
|
||||||
# plot baseline instantaneous frequency
|
# plot baseline instantaneous frequency
|
||||||
axs[3].plot(self.frequency_time, self.frequency)
|
ax3.plot(self.frequency_time, self.frequency)
|
||||||
|
|
||||||
# plot filtered and rectified envelope
|
# plot filtered and rectified envelope
|
||||||
axs[4].plot(self.time, self.baseline_envelope)
|
ax4.plot(self.time, self.baseline_envelope)
|
||||||
axs[4].scatter(
|
ax4.scatter(
|
||||||
(self.time)[self.baseline_peaks],
|
(self.time)[self.baseline_peaks],
|
||||||
self.baseline_envelope[self.baseline_peaks],
|
self.baseline_envelope[self.baseline_peaks],
|
||||||
c=ps.red,
|
c=ps.red,
|
||||||
)
|
)
|
||||||
|
|
||||||
# plot envelope of search signal
|
# plot envelope of search signal
|
||||||
axs[5].plot(self.time, self.search_envelope)
|
ax5.plot(self.time, self.search_envelope)
|
||||||
axs[5].scatter(
|
ax5.scatter(
|
||||||
(self.time)[self.search_peaks],
|
(self.time)[self.search_peaks],
|
||||||
self.search_envelope[self.search_peaks],
|
self.search_envelope[self.search_peaks],
|
||||||
c=ps.red,
|
c=ps.red,
|
||||||
)
|
)
|
||||||
|
|
||||||
# plot filtered instantaneous frequency
|
# plot filtered instantaneous frequency
|
||||||
axs[6].plot(self.frequency_time, self.frequency_filtered)
|
ax6.plot(self.frequency_time, self.frequency_filtered)
|
||||||
axs[6].scatter(
|
ax6.scatter(
|
||||||
self.frequency_time[self.frequency_peaks],
|
self.frequency_time[self.frequency_peaks],
|
||||||
self.frequency_filtered[self.frequency_peaks],
|
self.frequency_filtered[self.frequency_peaks],
|
||||||
c=ps.red,
|
c=ps.red,
|
||||||
)
|
)
|
||||||
axs[0].set_ylim(
|
ax0.set_ylim(
|
||||||
np.max(self.frequency) - 200, top=np.max(self.frequency) + 200
|
np.max(self.frequency) - 200, top=np.max(self.frequency) + 400
|
||||||
)
|
)
|
||||||
axs[6].set_xlabel("Time [s]")
|
ax0.set_title("Spectrogram of raw data")
|
||||||
axs[0].set_title("Spectrogram")
|
ax1.set_title("Extracted features")
|
||||||
axs[1].set_title("Fitered baseline")
|
ax4.set_title("Filtered and rectified features")
|
||||||
axs[2].set_title("Fitered above")
|
ax6.set_xlabel("Time [s]")
|
||||||
axs[3].set_title("Fitered baseline instanenous frequency")
|
|
||||||
axs[4].set_title("Filtered envelope of baseline envelope")
|
ax0.set_xlim(0, 5)
|
||||||
axs[5].set_title("Search envelope")
|
|
||||||
axs[6].set_title("Filtered absolute instantaneous frequency")
|
|
||||||
|
|
||||||
if plot == "show":
|
if plot == "show":
|
||||||
plt.show()
|
plt.show()
|
||||||
@ -172,7 +205,7 @@ def plot_spectrogram(
|
|||||||
spec_power, spec_freqs, spec_times = spectrogram(
|
spec_power, spec_freqs, spec_times = spectrogram(
|
||||||
signal,
|
signal,
|
||||||
ratetime=samplerate,
|
ratetime=samplerate,
|
||||||
freq_resolution=20,
|
freq_resolution=10,
|
||||||
overlap_frac=0.5,
|
overlap_frac=0.5,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -339,7 +372,7 @@ def find_searchband(
|
|||||||
|
|
||||||
q1, q2 = np.percentile(
|
q1, q2 = np.percentile(
|
||||||
data.freq[data.ident == check_track_id],
|
data.freq[data.ident == check_track_id],
|
||||||
config.search_freq_percentiles,
|
[25, 75]
|
||||||
)
|
)
|
||||||
|
|
||||||
search_window_bool[
|
search_window_bool[
|
||||||
@ -432,11 +465,13 @@ def main(datapath: str, plot: str) -> None:
|
|||||||
raw_time = np.arange(data.raw.shape[0]) / data.raw_rate
|
raw_time = np.arange(data.raw.shape[0]) / data.raw_rate
|
||||||
|
|
||||||
# good chirp times for data: 2022-06-02-10_00
|
# good chirp times for data: 2022-06-02-10_00
|
||||||
window_start_seconds = (3 * 60 * 60 + 6 * 60 + 43.5) * data.raw_rate
|
# window_start_seconds = (3 * 60 * 60 + 6 * 60 + 43.5) * data.raw_rate
|
||||||
window_duration_seconds = 60 * data.raw_rate
|
# window_duration_seconds = 60 * data.raw_rate
|
||||||
|
|
||||||
# t0 = 0
|
# t0 = 0
|
||||||
# dt = data.raw.shape[0]
|
# dt = data.raw.shape[0]
|
||||||
|
window_start_seconds = (23495 + ((28336-23495)/3)) * data.raw_rate
|
||||||
|
window_duration_seconds = (28336 - 23495) * data.raw_rate
|
||||||
|
|
||||||
# generate starting points of rolling window
|
# generate starting points of rolling window
|
||||||
window_start_indices = np.arange(
|
window_start_indices = np.arange(
|
||||||
@ -773,6 +808,7 @@ def main(datapath: str, plot: str) -> None:
|
|||||||
baseline=baselineband,
|
baseline=baselineband,
|
||||||
baseline_envelope=baseline_envelope,
|
baseline_envelope=baseline_envelope,
|
||||||
baseline_peaks=baseline_peak_indices,
|
baseline_peaks=baseline_peak_indices,
|
||||||
|
search_frequency=search_frequency,
|
||||||
search=searchband,
|
search=searchband,
|
||||||
search_envelope=search_envelope,
|
search_envelope=search_envelope,
|
||||||
search_peaks=search_peak_indices,
|
search_peaks=search_peak_indices,
|
||||||
@ -876,5 +912,6 @@ def main(datapath: str, plot: str) -> None:
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# datapath = "/home/weygoldt/Data/uni/chirpdetection/GP2023_chirp_detection/data/mount_data/2020-05-13-10_00/"
|
# datapath = "/home/weygoldt/Data/uni/chirpdetection/GP2023_chirp_detection/data/mount_data/2020-05-13-10_00/"
|
||||||
datapath = "../data/2022-06-02-10_00/"
|
# datapath = "../data/2022-06-02-10_00/"
|
||||||
|
datapath = "/home/weygoldt/Data/uni/efishdata/2016-colombia/fishgrid/2016-04-09-22_25/"
|
||||||
main(datapath, plot="show")
|
main(datapath, plot="show")
|
||||||
|
@ -3,6 +3,24 @@ from typing import List, Any
|
|||||||
from scipy.ndimage import gaussian_filter1d
|
from scipy.ndimage import gaussian_filter1d
|
||||||
|
|
||||||
|
|
||||||
|
def norm(data):
|
||||||
|
"""
|
||||||
|
Normalize data to [0, 1]
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
data : np.ndarray
|
||||||
|
Data to normalize.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
np.ndarray
|
||||||
|
Normalized data.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (2*((data - np.min(data)) / (np.max(data) - np.min(data)))) - 1
|
||||||
|
|
||||||
|
|
||||||
def instantaneous_frequency(
|
def instantaneous_frequency(
|
||||||
signal: np.ndarray,
|
signal: np.ndarray,
|
||||||
samplerate: int,
|
samplerate: int,
|
||||||
|
Loading…
Reference in New Issue
Block a user