4x4 Grid Microphones (Jupyter Notebook)

MD
S
Markdown

Interactive Viz with Data (grid 4x4)

import pandas as pd import numpy as np import plotly.graph_objects as go

Generate mock data

duration = 600 timestamps = np.arange(0, duration, 1) n_samples = len(timestamps)

def generate_clustered_data(n_samples, n_hydrophones=16): data = np.zeros((n_samples, n_hydrophones)) for t in range(n_samples): center = np.random.randint(0, 16) neighbors = [(center//4 + dx, center%4 + dy) for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)] if 0 <= center//4 + dx < 4 and 0 <= center%4 + dy < 4] n_activations = np.random.randint(2, 4) activations = [center] + [neighbors[i][0]*4 + neighbors[i][1] for i in np.random.choice(len(neighbors), min(n_activations-1, len(neighbors)), replace=False)] data[t, activations] = 1 return data

hydrophone_data = generate_clustered_data(n_samples) df = pd.DataFrame(hydrophone_data, columns=[f'H{i+1}' for i in range(16)]) df['Timestamp'] = timestamps

frames = [] for t in timestamps: data_at_t = df[df['Timestamp'] == t].iloc[0, :-1].values.reshape(4, 4) frames.append( go.Frame( data=[go.Heatmap( z=data_at_t, colorscale=[[0, 'lightgrey'], [1, 'red']], showscale=False, text=[[f'H{i*4+j+1}' for j in range(4)] for i in range(4)], texttemplate="%{text}", textfont={"size":10}, xgap=3, # Add gap between cells ygap=3, # Add gap between cells hoverongaps=False )], name=str(t) ) )

fig = go.Figure( data=[go.Heatmap( z=df.iloc[0, :-1].values.reshape(4, 4), colorscale=[[0, 'lightgrey'], [1, 'red']], showscale=False, text=[[f'H{i*4+j+1}' for j in range(4)] for i in range(4)], texttemplate="%{text}", textfont={"size":10}, xgap=3, # Add gap between cells ygap=3, # Add gap between cells hoverongaps=False )], frames=frames )

fig.update_layout( title="4x4 Hydrophone Grid Animation", updatemenus=[{ 'type': 'buttons', 'showactive': False, 'buttons': [ {'label': 'Play', 'method': 'animate', 'args': [None, {'frame': {'duration': 1000, 'redraw': True}, 'fromcurrent': True}]}, {'label': 'Pause', 'method': 'animate', 'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate', 'transition': {'duration': 0}}]} ] }], sliders=[{ 'currentvalue': {"prefix": "Time: ", "suffix": " seconds"}, 'steps': [{'args': [[str(t)], {'frame': {'duration': 0, 'redraw': True}, 'mode': 'immediate'}], 'label': str(t), 'method': 'animate'} for t in timestamps] }] )

Add grid styling

fig.update_layout( width=600, height=600, plot_bgcolor='white', xaxis=dict( showgrid=True, gridwidth=2, gridcolor='black', tickmode='array', ticktext=['1', '2', '3', '4'], tickvals=[0, 1, 2, 3] ), yaxis=dict( showgrid=True, gridwidth=2, gridcolor='black', tickmode='array', ticktext=['1', '2', '3', '4'], tickvals=[0, 1, 2, 3], scaleanchor='x' # Make cells square ) )

fig.show()

Created on 2/7/2025