This repository was archived by the owner on Aug 11, 2026. It is now read-only.
Commit 8114035
feat: add comprehensive spectrogram data access and visualization support
Resolves Issue #46
Add complete spectrogram support to enable programmatic access to the same
high-quality constant-Q spectrograms used in the IDTAP web application, with
extensive matplotlib integration for computational musicology research.
## New Features:
### SpectrogramData Class (`idtap/spectrogram.py`)
- **Data Loading**:
- `from_audio_id(audio_id, client)` - Download from server
- `from_piece(piece, client)` - Load from Piece object
- Auto-decompresses gzipped spectrogram data from swara.studio
- **Transformations**:
- `apply_intensity(power)` - Power-law contrast enhancement (1.0-5.0)
- `apply_colormap(data, cmap)` - 35+ matplotlib colormaps
- `crop_frequency(min_hz, max_hz)` - Frequency range cropping
- `crop_time(start_time, end_time)` - Time range cropping
- **Matplotlib Integration** (for research workflows):
- `plot_on_axis(ax, ...)` - Plot on existing axis for overlays
- `get_plot_data(power, apply_cmap, cmap)` - Get processed data + extent
- `get_extent()` - Get matplotlib extent [left, right, bottom, top]
- **Image Generation**:
- `to_image(width, height, power, cmap)` - Generate PIL Image
- `to_matplotlib(figsize, power, cmap)` - Generate standalone figure
- `save(filepath, ...)` - Save to file (PNG, JPG, etc.)
- **Properties**:
- `shape`, `duration`, `time_resolution`, `freq_bins`
### SwaraClient Updates (`idtap/client.py`)
- `download_spectrogram_data(audio_id)` - Download compressed data
- `download_spectrogram_metadata(audio_id)` - Download shape metadata
### Dependencies (`pyproject.toml`, `Pipfile`)
- Added `numpy>=1.20.0` for array processing
- Added `pillow>=9.0.0` for image generation
- Added `matplotlib>=3.5.0` for visualization
## Testing:
- 36 comprehensive test cases covering:
- Data loading and initialization
- Intensity transforms and colormap application
- Frequency and time cropping
- Matplotlib integration methods
- Image generation and saving
- All properties and edge cases
- **All 401 tests pass** (365 existing + 36 new)
## Usage Example:
```python
from idtap import SpectrogramData, get_piece
import matplotlib.pyplot as plt
# Load spectrogram
piece = get_piece("transcription_id")
spec = SpectrogramData.from_piece(piece)
# Create visualization with spectrogram underlay
fig, ax = plt.subplots(figsize=(12, 6))
spec.plot_on_axis(ax, power=2.5, cmap='viridis', alpha=0.6, zorder=0)
# Overlay pitch contour
ax.plot(times, freqs, 'r-', linewidth=2, zorder=1)
ax.set_xlabel('Time (s)')
ax.set_ylabel('Frequency (Hz)')
plt.savefig('figure.png', dpi=300)
```
## Documentation Updates:
- Updated CLAUDE.md with testing warning about browser authorization
## Design Decisions:
- Follows librosa/matplotlib patterns for research workflows
- Optional client parameter (creates if not provided)
- No caching in MVP (users can cache manually)
- Uses matplotlib colormaps (close enough to D3, simpler)
- Loads entire spectrogram into memory (suitable for typical sizes)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>1 parent 2a32c12 commit 8114035
8 files changed
Lines changed: 1880 additions & 273 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
19 | 24 | | |
20 | 25 | | |
21 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
18 | 21 | | |
19 | 22 | | |
20 | 23 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
| |||
74 | 75 | | |
75 | 76 | | |
76 | 77 | | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
77 | 81 | | |
78 | 82 | | |
79 | 83 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
684 | 684 | | |
685 | 685 | | |
686 | 686 | | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
687 | 711 | | |
688 | 712 | | |
689 | 713 | | |
| |||
0 commit comments