4x4 Grid Microphones (Jupyter Notebook)

MD
S
Markdown

Interactive Viz with Data (grid 4x4)

1import pandas as pd
2import numpy as np
3import plotly.graph_objects as go
4
5# Generate mock data
6duration = 600
7timestamps = np.arange(0, duration, 1)
8n_samples = len(timestamps)
9
10def generate_clustered_data(n_samples, n_hydrophones=16):
11    data = np.zeros((n_samples, n_hydrophones))
12    for t in range(n_samples):
13        center = np.random.randint(0, 16)
14        neighbors = [(center//4 + dx, center%4 + dy) for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)]
15                    if 0 <= center//4 + dx < 4 and 0 <= center%4 + dy < 4]
16        n_activations = np.random.randint(2, 4)
17        activations = [center] + [neighbors[i][0]*4 + neighbors[i][1] 
18                                for i in np.random.choice(len(neighbors), 
19                                min(n_activations-1, len(neighbors)), replace=False)]
20        data[t, activations] = 1
21    return data
22
23hydrophone_data = generate_clustered_data(n_samples)
24df = pd.DataFrame(hydrophone_data, columns=[f'H{i+1}' for i in range(16)])
25df['Timestamp'] = timestamps
26
27frames = []
28for t in timestamps:
29    data_at_t = df[df['Timestamp'] == t].iloc[0, :-1].values.reshape(4, 4)
30    frames.append(
31        go.Frame(
32            data=[go.Heatmap(
33                z=data_at_t,
34                colorscale=[[0, 'lightgrey'], [1, 'red']],
35                showscale=False,
36                text=[[f'H{i*4+j+1}' for j in range(4)] for i in range(4)],
37                texttemplate="%{text}",
38                textfont={"size":10},
39                xgap=3,  # Add gap between cells
40                ygap=3,  # Add gap between cells
41                hoverongaps=False
42            )],
43            name=str(t)
44        )
45    )
46
47fig = go.Figure(
48    data=[go.Heatmap(
49        z=df.iloc[0, :-1].values.reshape(4, 4),
50        colorscale=[[0, 'lightgrey'], [1, 'red']],
51        showscale=False,
52        text=[[f'H{i*4+j+1}' for j in range(4)] for i in range(4)],
53        texttemplate="%{text}",
54        textfont={"size":10},
55        xgap=3,  # Add gap between cells
56        ygap=3,  # Add gap between cells
57        hoverongaps=False
58    )],
59    frames=frames
60)
61
62fig.update_layout(
63    title="4x4 Hydrophone Grid Animation",
64    updatemenus=[{
65        'type': 'buttons',
66        'showactive': False,
67        'buttons': [
68            {'label': 'Play',
69             'method': 'animate',
70             'args': [None, {'frame': {'duration': 1000, 'redraw': True},
71                            'fromcurrent': True}]},
72            {'label': 'Pause',
73             'method': 'animate',
74             'args': [[None], {'frame': {'duration': 0, 'redraw': False},
75                              'mode': 'immediate',
76                              'transition': {'duration': 0}}]}
77        ]
78    }],
79    sliders=[{
80        'currentvalue': {"prefix": "Time: ", "suffix": " seconds"},
81        'steps': [{'args': [[str(t)],
82                           {'frame': {'duration': 0, 'redraw': True},
83                            'mode': 'immediate'}],
84                   'label': str(t),
85                   'method': 'animate'} for t in timestamps]
86    }]
87)
88
89# Add grid styling
90fig.update_layout(
91    width=600, 
92    height=600,
93    plot_bgcolor='white',
94    xaxis=dict(
95        showgrid=True,
96        gridwidth=2,
97        gridcolor='black',
98        tickmode='array',
99        ticktext=['1', '2', '3', '4'],
100        tickvals=[0, 1, 2, 3]
101    ),
102    yaxis=dict(
103        showgrid=True,
104        gridwidth=2,
105        gridcolor='black',
106        tickmode='array',
107        ticktext=['1', '2', '3', '4'],
108        tickvals=[0, 1, 2, 3],
109        scaleanchor='x'  # Make cells square
110    )
111)
112
113fig.show()

Created on 2/7/2025