Source code for nwbwidgets.spectrum

import numpy as np
import matplotlib.pyplot as plt

from ipywidgets import widgets

from ndx_spectrum import Spectrum


[docs]def show_spectrum(node: Spectrum, **kwargs) -> widgets.Widget: check_spectrum(node) data = node.power if "power" in node.fields else node.phase if len(data.shape) == 2: no_channels = data.shape[1] else: no_channels = 1 freqs_all = np.asarray(node.frequencies) channel_slider = widgets.IntRangeSlider( min=1, max=no_channels, step=1, description="Channel Range:", disabled=False, continuous_update=False, orientation="horizontal", readout=True, readout_format="d", ) freq_slider = widgets.IntRangeSlider( min=0, max=freqs_all[-1], step=1, description="Frequency Range:", disabled=False, continuous_update=False, orientation="horizontal", readout=True, readout_format="d", ) out = widgets.Output() with out: widgets.interact( lambda channel_range, frequency_range: plot_spectrum_figure( node, channel_range, frequency_range ), channel_range=channel_slider, frequency_range=freq_slider, ) return out
[docs]def plot_spectrum_figure(spectrum, channel_nos, frequency_nos): """ Plot power vs frequencies and/or phase vs frequencies. Parameters ---------- spectrum: Spectrum channel_nos: tuple Input from the channel range slider widget: (channel_no start, channel_no end) frequency_nos: tuple Input from frequency range slider widget: (freq start, freq end) """ check_spectrum(spectrum) all_freqs = np.asarray(spectrum.frequencies) start_id = (np.abs(frequency_nos[0] - all_freqs)).argmin() end_id = (np.abs(frequency_nos[1] - all_freqs)).argmin() if channel_nos[0] != channel_nos[1]: range_ = range(channel_nos[0] - 1, channel_nos[1] - 1) else: range_ = channel_nos[0] - 1 if "power" in spectrum.fields: power_data = np.asarray(spectrum.power) if len(power_data.shape) == 1: power_data = power_data[:, np.newaxis] if "phase" in spectrum.fields: phase_data = np.asarray(spectrum.phase) if len(phase_data.shape) == 1: phase_data = phase_data[:, np.newaxis] # make plots: if "power" in spectrum.fields and "phase" in spectrum.fields: fig, axs = plt.subplots(2, 1, sharex=True) axs[0].semilogy(all_freqs[start_id:end_id], power_data[start_id:end_id, range_]) axs[0].set_ylabel("Power") axs[1].plot(all_freqs[start_id:end_id], phase_data[start_id:end_id, range_]) axs[1].set_ylabel("phase") elif "power" in spectrum.fields: fig, ax = plt.subplots() ax.set_xlabel("frequency") ax.semilogy(all_freqs[start_id:end_id], power_data[start_id:end_id, range_]) ax.set_ylabel("Power") elif "phase" in spectrum.fields: fig, ax = plt.subplots() ax.plot(all_freqs[start_id:end_id], phase_data[start_id:end_id, range_]) ax.set_ylabel("phase") ax.set_xlabel("frequency")
[docs]def check_spectrum(node): assert isinstance(node, Spectrum), "datatype not of type Spectrum" assert "frequencies" in node.fields, "frequencies not found in Spectrum" assert ( "power" in node.fields or "phase" in node.fields ), "neither of power/phase found in Spectrum" if "power" in node.fields and "phase" in node.fields: assert ( node.power.shape == node.phase.shape ), "power and phase arrays should be of same dims"