|
1 | | -""" pyplots.ai |
| 1 | +""" anyplot.ai |
2 | 2 | andrews-curves: Andrews Curves for Multivariate Data |
3 | | -Library: seaborn 0.13.2 | Python 3.13.11 |
4 | | -Quality: 92/100 | Created: 2025-12-30 |
| 3 | +Library: seaborn 0.13.2 | Python 3.13.13 |
| 4 | +Quality: 92/100 | Updated: 2026-05-15 |
5 | 5 | """ |
6 | 6 |
|
7 | | -import matplotlib.pyplot as plt |
8 | | -import numpy as np |
9 | | -import pandas as pd |
10 | | -import seaborn as sns |
| 7 | +import os |
| 8 | +import sys |
11 | 9 |
|
12 | 10 |
|
13 | | -# Load iris dataset from seaborn |
| 11 | +# Handle import shadowing: remove current directory from path to avoid |
| 12 | +# importing local matplotlib.py or seaborn.py instead of the real libraries |
| 13 | +cwd = os.path.dirname(os.path.abspath(__file__)) |
| 14 | +sys.path = [p for p in sys.path if not (p == cwd or p.startswith(cwd + os.sep))] |
| 15 | + |
| 16 | +import matplotlib.pyplot as plt # noqa: E402 |
| 17 | +import numpy as np # noqa: E402 |
| 18 | +import pandas as pd # noqa: E402 |
| 19 | +import seaborn as sns # noqa: E402 |
| 20 | + |
| 21 | + |
| 22 | +# Theme tokens |
| 23 | +THEME = os.getenv("ANYPLOT_THEME", "light") |
| 24 | +PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
| 25 | +ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420" |
| 26 | +INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
| 27 | +INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0" |
| 28 | + |
| 29 | +# Okabe-Ito palette (first series always #009E73) |
| 30 | +OKABE_ITO = [ |
| 31 | + "#009E73", # bluish green (brand) |
| 32 | + "#D55E00", # vermillion |
| 33 | + "#0072B2", # blue |
| 34 | +] |
| 35 | + |
| 36 | +# Data |
14 | 37 | df = sns.load_dataset("iris") |
15 | 38 |
|
16 | 39 | # Normalize variables to similar scales |
|
20 | 43 |
|
21 | 44 | norm_features = [f + "_norm" for f in features] |
22 | 45 |
|
23 | | -# Generate t values from -pi to pi |
| 46 | +# Generate t values from -π to π |
24 | 47 | t = np.linspace(-np.pi, np.pi, 200) |
25 | 48 |
|
26 | 49 | # Compute Andrews curves for all observations |
27 | | -# Andrews curve: f(t) = x1/sqrt(2) + x2*sin(t) + x3*cos(t) + x4*sin(2t) + ... |
28 | 50 | curves_data = [] |
29 | 51 | for idx, row in df.iterrows(): |
30 | 52 | values = row[norm_features].values.astype(float) |
31 | | - # Compute Fourier series for this observation |
| 53 | + # Andrews curve: f(t) = x1/sqrt(2) + x2*sin(t) + x3*cos(t) + x4*sin(2t) + ... |
32 | 54 | curve_vals = np.full_like(t, values[0] / np.sqrt(2)) |
33 | 55 | for i in range(1, len(values)): |
34 | 56 | if i % 2 == 1: |
|
41 | 63 |
|
42 | 64 | curves_df = pd.DataFrame(curves_data) |
43 | 65 |
|
44 | | -# Color palette using Python Blue, Yellow, and a third color |
45 | | -colors = {"setosa": "#306998", "versicolor": "#FFD43B", "virginica": "#E74C3C"} |
| 66 | +# Theme-adaptive seaborn styling |
| 67 | +sns.set_theme( |
| 68 | + style="ticks", |
| 69 | + rc={ |
| 70 | + "figure.facecolor": PAGE_BG, |
| 71 | + "axes.facecolor": PAGE_BG, |
| 72 | + "axes.edgecolor": INK_SOFT, |
| 73 | + "axes.labelcolor": INK, |
| 74 | + "text.color": INK, |
| 75 | + "xtick.color": INK_SOFT, |
| 76 | + "ytick.color": INK_SOFT, |
| 77 | + "grid.color": INK, |
| 78 | + "grid.alpha": 0.10, |
| 79 | + "legend.facecolor": ELEVATED_BG, |
| 80 | + "legend.edgecolor": INK_SOFT, |
| 81 | + }, |
| 82 | +) |
46 | 83 |
|
47 | | -# Create plot |
| 84 | +# Plot |
48 | 85 | fig, ax = plt.subplots(figsize=(16, 9)) |
49 | | -sns.set_style("whitegrid") |
50 | 86 |
|
51 | 87 | # Plot Andrews curves using lineplot with grouped data |
52 | 88 | sns.lineplot( |
53 | 89 | data=curves_df, |
54 | 90 | x="t", |
55 | 91 | y="f(t)", |
56 | 92 | hue="species", |
57 | | - palette=colors, |
| 93 | + palette=OKABE_ITO, |
58 | 94 | alpha=0.4, |
59 | | - linewidth=1.5, |
| 95 | + linewidth=2.5, |
60 | 96 | units="obs_id", |
61 | 97 | estimator=None, |
62 | 98 | ax=ax, |
63 | 99 | ) |
64 | 100 |
|
65 | | -# Style the plot |
66 | | -ax.set_xlabel("t", fontsize=20) |
67 | | -ax.set_ylabel("f(t)", fontsize=20) |
68 | | -ax.set_title("andrews-curves · seaborn · pyplots.ai", fontsize=24) |
69 | | -ax.tick_params(axis="both", labelsize=16) |
| 101 | +# Style |
| 102 | +ax.set_xlabel("t", fontsize=20, color=INK) |
| 103 | +ax.set_ylabel("f(t)", fontsize=20, color=INK) |
| 104 | +ax.set_title("andrews-curves · seaborn · anyplot.ai", fontsize=24, color=INK) |
| 105 | +ax.tick_params(axis="both", labelsize=16, colors=INK_SOFT) |
70 | 106 |
|
71 | | -# Set x-axis ticks to show pi values |
| 107 | +# Set x-axis ticks to show π values |
72 | 108 | ax.set_xticks([-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi]) |
73 | 109 | ax.set_xticklabels(["-π", "-π/2", "0", "π/2", "π"], fontsize=16) |
74 | 110 |
|
75 | | -# Customize legend |
76 | | -ax.legend(title="Species", fontsize=16, title_fontsize=18, loc="upper right") |
| 111 | +# Legend |
| 112 | +ax.legend(title="Species", fontsize=16, title_fontsize=18, loc="upper right", framealpha=0.95) |
77 | 113 |
|
78 | | -# Subtle grid |
79 | | -ax.grid(True, alpha=0.3, linestyle="--") |
| 114 | +# Grid (subtle, solid lines) |
| 115 | +ax.grid(True, alpha=0.10, linewidth=0.8, linestyle="-") |
| 116 | +ax.spines["top"].set_visible(False) |
| 117 | +ax.spines["right"].set_visible(False) |
80 | 118 |
|
81 | 119 | plt.tight_layout() |
82 | | -plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
| 120 | +plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG) |
0 commit comments