Skip to content

Commit 4af0bf4

Browse files
feat(plotnine): implement spectrum-basic (#2968)
## Implementation: `spectrum-basic` - plotnine Implements the **plotnine** version of `spectrum-basic`. **File:** `plots/spectrum-basic/implementations/plotnine.py` **Parent Issue:** #2926 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20612836373)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 6184baa commit 4af0bf4

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
""" pyplots.ai
2+
spectrum-basic: Frequency Spectrum Plot
3+
Library: plotnine 0.15.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-31
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from plotnine import (
10+
aes,
11+
annotation_logticks,
12+
element_text,
13+
geom_line,
14+
ggplot,
15+
labs,
16+
scale_x_log10,
17+
theme,
18+
theme_minimal,
19+
)
20+
21+
22+
# Data: Create a synthetic signal with multiple frequency components
23+
np.random.seed(42)
24+
25+
# Sampling parameters
26+
sample_rate = 4096 # Hz
27+
duration = 1.0 # seconds
28+
n_samples = int(sample_rate * duration)
29+
t = np.linspace(0, duration, n_samples, endpoint=False)
30+
31+
# Create signal with multiple frequency components
32+
# Simulating a mechanical vibration signal with fundamental and harmonics
33+
fundamental_freq = 50 # Hz (e.g., motor rotation)
34+
signal = (
35+
1.0 * np.sin(2 * np.pi * fundamental_freq * t) # Fundamental
36+
+ 0.5 * np.sin(2 * np.pi * 2 * fundamental_freq * t) # 2nd harmonic
37+
+ 0.25 * np.sin(2 * np.pi * 3 * fundamental_freq * t) # 3rd harmonic
38+
+ 0.15 * np.sin(2 * np.pi * 500 * t) # High frequency component
39+
+ 0.1 * np.random.randn(n_samples) # Noise
40+
)
41+
42+
# Compute FFT
43+
fft_result = np.fft.fft(signal)
44+
frequencies = np.fft.fftfreq(n_samples, 1 / sample_rate)
45+
46+
# Take positive frequencies only
47+
positive_mask = frequencies > 0
48+
frequencies = frequencies[positive_mask]
49+
amplitudes = np.abs(fft_result[positive_mask]) * 2 / n_samples
50+
51+
# Convert to dB scale for better visualization
52+
amplitudes_db = 20 * np.log10(amplitudes + 1e-10)
53+
54+
# Create DataFrame for plotnine
55+
df = pd.DataFrame({"frequency": frequencies, "amplitude": amplitudes_db})
56+
57+
# Filter to relevant frequency range (10 Hz to 1000 Hz)
58+
df = df[(df["frequency"] >= 10) & (df["frequency"] <= 1000)]
59+
60+
# Create plot
61+
plot = (
62+
ggplot(df, aes(x="frequency", y="amplitude"))
63+
+ geom_line(color="#306998", size=1.2, alpha=0.9)
64+
+ scale_x_log10()
65+
+ annotation_logticks(sides="b")
66+
+ labs(x="Frequency (Hz)", y="Amplitude (dB)", title="spectrum-basic · plotnine · pyplots.ai")
67+
+ theme_minimal()
68+
+ theme(
69+
figure_size=(16, 9),
70+
plot_title=element_text(size=24, face="bold"),
71+
axis_title=element_text(size=20),
72+
axis_text=element_text(size=16),
73+
panel_grid_major=element_text(alpha=0.3),
74+
)
75+
)
76+
77+
# Save
78+
plot.save("plot.png", dpi=300, verbose=False)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: plotnine
2+
specification_id: spectrum-basic
3+
created: '2025-12-31T05:36:25Z'
4+
updated: '2025-12-31T05:50:10Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20612836373
7+
issue: 2926
8+
python_version: 3.13.11
9+
library_version: 0.15.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/spectrum-basic/plotnine/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/spectrum-basic/plotnine/plot_thumb.png
12+
preview_html: null
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent signal processing implementation with realistic mechanical vibration
17+
scenario showing fundamental and harmonics
18+
- Proper use of logarithmic frequency scale with annotation_logticks for professional
19+
axis presentation
20+
- Clear axis labels with appropriate units (Hz, dB)
21+
- Good use of dB scale for amplitude visualization as recommended in spec
22+
- Clean KISS code structure with proper FFT computation
23+
weaknesses:
24+
- Grid lines not visible because panel_grid_major=element_text(alpha=0.3) uses wrong
25+
element type - should be element_line not element_text

0 commit comments

Comments
 (0)