Skip to content

Commit 0164622

Browse files
feat(matplotlib): implement spectrum-basic (#2950)
## Implementation: `spectrum-basic` - matplotlib Implements the **matplotlib** version of `spectrum-basic`. **File:** `plots/spectrum-basic/implementations/matplotlib.py` **Parent Issue:** #2926 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20612813068)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent b8bf881 commit 0164622

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
""" pyplots.ai
2+
spectrum-basic: Frequency Spectrum Plot
3+
Library: matplotlib 3.10.8 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-31
5+
"""
6+
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
10+
11+
# Generate synthetic signal with multiple frequency components
12+
np.random.seed(42)
13+
14+
# Sampling parameters
15+
sample_rate = 1000 # Hz
16+
duration = 1.0 # seconds
17+
n_samples = int(sample_rate * duration)
18+
t = np.linspace(0, duration, n_samples, endpoint=False)
19+
20+
# Create signal with multiple frequency components
21+
# 50 Hz fundamental, 120 Hz harmonic, 200 Hz component, plus noise
22+
signal = (
23+
1.0 * np.sin(2 * np.pi * 50 * t) # 50 Hz fundamental
24+
+ 0.5 * np.sin(2 * np.pi * 120 * t) # 120 Hz harmonic
25+
+ 0.3 * np.sin(2 * np.pi * 200 * t) # 200 Hz component
26+
+ 0.1 * np.random.randn(n_samples) # Noise
27+
)
28+
29+
# Compute FFT
30+
fft_result = np.fft.fft(signal)
31+
frequencies = np.fft.fftfreq(n_samples, 1 / sample_rate)
32+
33+
# Take only positive frequencies
34+
positive_mask = frequencies >= 0
35+
frequencies = frequencies[positive_mask]
36+
amplitude = np.abs(fft_result[positive_mask]) * 2 / n_samples # Normalized amplitude
37+
38+
# Convert to dB scale (with floor to avoid log of zero)
39+
amplitude_db = 20 * np.log10(amplitude + 1e-10)
40+
41+
# Create plot
42+
fig, ax = plt.subplots(figsize=(16, 9))
43+
44+
# Plot spectrum
45+
ax.plot(frequencies, amplitude_db, linewidth=2.5, color="#306998", alpha=0.9)
46+
47+
# Fill under the curve for visual emphasis
48+
ax.fill_between(frequencies, amplitude_db, alpha=0.3, color="#306998")
49+
50+
# Mark peak frequencies
51+
peaks = [50, 120, 200]
52+
for peak_freq in peaks:
53+
idx = np.argmin(np.abs(frequencies - peak_freq))
54+
ax.axvline(x=peak_freq, color="#FFD43B", linestyle="--", linewidth=2, alpha=0.8)
55+
ax.scatter(
56+
[frequencies[idx]], [amplitude_db[idx]], s=200, color="#FFD43B", zorder=5, edgecolors="black", linewidths=1.5
57+
)
58+
ax.annotate(
59+
f"{peak_freq} Hz",
60+
xy=(frequencies[idx], amplitude_db[idx]),
61+
xytext=(10, 10),
62+
textcoords="offset points",
63+
fontsize=14,
64+
fontweight="bold",
65+
color="#306998",
66+
)
67+
68+
# Styling
69+
ax.set_xlabel("Frequency (Hz)", fontsize=20)
70+
ax.set_ylabel("Amplitude (dB)", fontsize=20)
71+
ax.set_title("spectrum-basic · matplotlib · pyplots.ai", fontsize=24)
72+
ax.tick_params(axis="both", labelsize=16)
73+
ax.grid(True, alpha=0.3, linestyle="--")
74+
75+
# Set axis limits
76+
ax.set_xlim(0, 300)
77+
ax.set_ylim(-60, 10)
78+
79+
plt.tight_layout()
80+
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library: matplotlib
2+
specification_id: spectrum-basic
3+
created: '2025-12-31T05:33:30Z'
4+
updated: '2025-12-31T05:45:00Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20612813068
7+
issue: 2926
8+
python_version: 3.13.11
9+
library_version: 3.10.8
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/spectrum-basic/matplotlib/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/spectrum-basic/matplotlib/plot_thumb.png
12+
preview_html: null
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent signal processing implementation with proper FFT computation and normalization
17+
- Clear visualization of frequency peaks with effective use of annotations and vertical
18+
reference lines
19+
- Professional styling with appropriate font sizes meeting 4800×2700 resolution
20+
requirements
21+
- dB scale properly implemented with floor to avoid log(0)
22+
- Fill under curve provides good visual emphasis of the spectrum shape
23+
weaknesses:
24+
- Line width (2.5) could be increased to 3 for better visibility at full resolution
25+
- No legend present, though for this single-series plot it is acceptable
26+
- Could use more distinctive matplotlib features like spine customization or logarithmic
27+
frequency scale option

0 commit comments

Comments
 (0)