{"spec_id":"spectrum-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nspectrum-basic: Frequency Spectrum Plot\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 93/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nBRAND = \"#009E73\"  # Okabe-Ito position 1\nACCENT = \"#C475FD\"  # Okabe-Ito position 2 for annotations\n\n# Generate synthetic signal with multiple frequency components\nnp.random.seed(42)\n\n# Sampling parameters\nsample_rate = 1000  # Hz\nduration = 1.0  # seconds\nn_samples = int(sample_rate * duration)\nt = np.linspace(0, duration, n_samples, endpoint=False)\n\n# Create signal with multiple frequency components\nsignal = (\n    1.0 * np.sin(2 * np.pi * 50 * t)  # 50 Hz fundamental\n    + 0.5 * np.sin(2 * np.pi * 120 * t)  # 120 Hz harmonic\n    + 0.3 * np.sin(2 * np.pi * 200 * t)  # 200 Hz component\n    + 0.1 * np.random.randn(n_samples)  # Noise\n)\n\n# Compute FFT\nfft_result = np.fft.fft(signal)\nfrequencies = np.fft.fftfreq(n_samples, 1 / sample_rate)\n\n# Take only positive frequencies\npositive_mask = frequencies >= 0\nfrequencies = frequencies[positive_mask]\namplitude = np.abs(fft_result[positive_mask]) * 2 / n_samples\n\n# Convert to dB scale\namplitude_db = 20 * np.log10(amplitude + 1e-10)\n\n# Plot\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Plot spectrum line\nax.plot(frequencies, amplitude_db, linewidth=3, color=BRAND, alpha=0.9)\n\n# Fill under the curve\nax.fill_between(frequencies, amplitude_db, alpha=0.25, color=BRAND)\n\n# Mark peak frequencies\npeaks = [50, 120, 200]\nfor peak_freq in peaks:\n    idx = np.argmin(np.abs(frequencies - peak_freq))\n    ax.axvline(x=peak_freq, color=ACCENT, linestyle=\"--\", linewidth=2, alpha=0.7)\n    ax.scatter(\n        [frequencies[idx]], [amplitude_db[idx]], s=200, color=ACCENT, zorder=5, edgecolors=PAGE_BG, linewidth=1.5\n    )\n    ax.annotate(\n        f\"{peak_freq} Hz\",\n        xy=(frequencies[idx], amplitude_db[idx]),\n        xytext=(10, 10),\n        textcoords=\"offset points\",\n        fontsize=14,\n        fontweight=\"bold\",\n        color=INK,\n        bbox={\n            \"facecolor\": PAGE_BG if THEME == \"light\" else \"#242420\",\n            \"edgecolor\": INK_SOFT,\n            \"alpha\": 0.8,\n            \"boxstyle\": \"round,pad=0.3\",\n        },\n    )\n\n# Style\nax.set_xlabel(\"Frequency (Hz)\", fontsize=20, color=INK)\nax.set_ylabel(\"Amplitude (dB)\", fontsize=20, color=INK)\nax.set_title(\"spectrum-basic · matplotlib · anyplot.ai\", fontsize=24, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\n\n# Spine styling\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\n\n# Grid\nax.grid(True, alpha=0.1, linewidth=0.8, color=INK)\n\n# Axis limits\nax.set_xlim(0, 300)\nax.set_ylim(-60, 10)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}