Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions plots/andrews-curves/implementations/matplotlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
""" pyplots.ai
andrews-curves: Andrews Curves for Multivariate Data
Library: matplotlib 3.10.8 | Python 3.13.11
Quality: 91/100 | Created: 2025-12-30
"""

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler


# Load and prepare data
iris = load_iris()
X = iris.data
y = iris.target
species_names = ["Setosa", "Versicolor", "Virginica"]

# Normalize data to prevent dominant variables
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Generate t values from -π to π
t = np.linspace(-np.pi, np.pi, 200)

# Build Andrews curve transformation matrix
# f(t) = x1/sqrt(2) + x2*sin(t) + x3*cos(t) + x4*sin(2t) + ...
n_features = X_scaled.shape[1]
basis = np.zeros((len(t), n_features))
basis[:, 0] = 1 / np.sqrt(2)
for i in range(1, n_features):
freq = (i + 1) // 2
if i % 2 == 1:
basis[:, i] = np.sin(freq * t)
else:
basis[:, i] = np.cos(freq * t)

# Compute all Andrews curves: each row of X_scaled dot basis.T gives one curve
curves = X_scaled @ basis.T # shape: (150, 200)

# Create plot
fig, ax = plt.subplots(figsize=(16, 9))

# Colors for each species (Python Blue, Python Yellow, and a complementary color)
colors = ["#306998", "#FFD43B", "#E06C75"]

# Plot Andrews curves for each observation
for i in range(len(curves)):
ax.plot(t, curves[i], color=colors[y[i]], alpha=0.4, linewidth=1.5)

# Create legend with sample lines
for idx, species in enumerate(species_names):
ax.plot([], [], color=colors[idx], linewidth=3, label=species, alpha=0.8)

# Styling
ax.set_xlabel("t (radians)", fontsize=20)
ax.set_ylabel("f(t)", fontsize=20)
ax.set_title("andrews-curves · matplotlib · pyplots.ai", fontsize=24)
ax.tick_params(axis="both", labelsize=16)
ax.legend(fontsize=16, loc="upper right")
ax.grid(True, alpha=0.3, linestyle="--")

# Set x-axis ticks at meaningful positions
ax.set_xticks([-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi])
ax.set_xticklabels(["-π", "-π/2", "0", "π/2", "π"], fontsize=16)

plt.tight_layout()
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
28 changes: 28 additions & 0 deletions plots/andrews-curves/metadata/matplotlib.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
library: matplotlib
specification_id: andrews-curves
created: '2025-12-30T23:55:55Z'
updated: '2025-12-31T00:02:02Z'
generated_by: claude-opus-4-5-20251101
workflow_run: 20608490813
issue: 2859
python_version: 3.13.11
library_version: 3.10.8
preview_url: https://storage.googleapis.com/pyplots-images/plots/andrews-curves/matplotlib/plot.png
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/andrews-curves/matplotlib/plot_thumb.png
preview_html: null
quality_score: 91
review:
strengths:
- Excellent implementation of Andrews curves algorithm using Fourier basis functions
- Clean visualization that clearly shows Setosa species separation from Versicolor/Virginica
- Proper normalization with StandardScaler prevents dominant variables
- Appropriate transparency (alpha=0.4) for 150 overlapping curves reveals density
patterns
- X-axis uses mathematically meaningful tick labels (-π, -π/2, 0, π/2, π)
weaknesses:
- Missing np.random.seed(42) in code (though Iris dataset is deterministic, best
practice is to include it)
- Linewidth=1.5 is slightly below recommended 2-4 for high-resolution plots per
library guidelines
- Legend sample lines use alpha=0.8 while actual curves use alpha=0.4, creating
visual inconsistency