1- """ pyplots .ai
1+ """ anyplot .ai
22andrews-curves: Andrews Curves for Multivariate Data
3- Library: highcharts unknown | Python 3.13.11
4- Quality: 92 /100 | Created: 2025-12-31
3+ Library: highcharts unknown | Python 3.13.13
4+ Quality: 83 /100 | Updated: 2026-05-15
55"""
66
7+ import os
78import tempfile
89import time
910import urllib .request
1213import numpy as np
1314from highcharts_core .chart import Chart
1415from highcharts_core .options import HighchartsOptions
15- from highcharts_core .options .series .area import LineSeries
16+ from highcharts_core .options .series .spline import SplineSeries
1617from selenium import webdriver
1718from selenium .webdriver .chrome .options import Options
1819from sklearn .datasets import load_iris
1920from sklearn .preprocessing import StandardScaler
2021
2122
22- # Data - Iris dataset normalized
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+ GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)"
29+
30+ BRAND = "#009E73"
31+ OKABE_ITO = ["#009E73" , "#D55E00" , "#0072B2" ]
32+
2333iris = load_iris ()
2434X = StandardScaler ().fit_transform (iris .data )
2535y = iris .target
2636species_names = ["Setosa" , "Versicolor" , "Virginica" ]
2737
28- # Andrews curve transformation: f(t) = x1/sqrt(2) + x2*sin(t) + x3*cos(t) + x4*sin(2t) + ...
2938t = np .linspace (- np .pi , np .pi , 200 )
3039
3140
3241def andrews_curve (x , t ):
33- """Transform multivariate observation to Andrews curve"""
3442 n = len (x )
3543 result = x [0 ] / np .sqrt (2 )
3644 for i in range (1 , n ):
@@ -41,77 +49,67 @@ def andrews_curve(x, t):
4149 return result
4250
4351
44- # Create chart
4552chart = Chart (container = "container" )
4653chart .options = HighchartsOptions ()
4754
48- # Chart settings
4955chart .options .chart = {
5056 "type" : "line" ,
5157 "width" : 4800 ,
5258 "height" : 2700 ,
53- "backgroundColor" : "#ffffff" ,
59+ "backgroundColor" : PAGE_BG ,
5460 "marginBottom" : 180 ,
5561 "marginTop" : 120 ,
5662 "marginLeft" : 150 ,
5763 "marginRight" : 100 ,
5864}
5965
60- # Title
6166chart .options .title = {
62- "text" : "Iris Species · andrews-curves · highcharts · pyplots .ai" ,
63- "style" : {"fontSize" : "56px " , "fontWeight " : "bold" },
64- "y" : 60 ,
67+ "text" : "andrews-curves · highcharts · anyplot .ai" ,
68+ "style" : {"fontSize" : "28px " , "color " : INK },
69+ "y" : 30 ,
6570}
6671
67- # Axes
6872chart .options .x_axis = {
69- "title" : {"text" : "t (radians)" , "style" : {"fontSize" : "40px" }, "margin" : 30 },
70- "labels" : {"style" : {"fontSize" : "32px" }, "y" : 40 },
71- "gridLineWidth" : 1 ,
72- "gridLineColor" : "rgba(0,0,0,0.15)" ,
73+ "title" : {"text" : "t (radians)" , "style" : {"fontSize" : "22px" , "color" : INK }},
74+ "labels" : {"style" : {"fontSize" : "18px" , "color" : INK_SOFT }},
75+ "lineColor" : INK_SOFT ,
76+ "tickColor" : INK_SOFT ,
77+ "gridLineColor" : GRID ,
7378 "tickInterval" : 1 ,
7479 "min" : - 3.15 ,
7580 "max" : 3.15 ,
7681}
7782
7883chart .options .y_axis = {
79- "title" : {"text" : "f(t)" , "style" : {"fontSize" : "40px" }, "margin" : 30 },
80- "labels" : {"style" : {"fontSize" : "32px" }, "x" : - 15 },
81- "gridLineWidth" : 1 ,
82- "gridLineColor" : "rgba(0,0,0,0.15)" ,
84+ "title" : {"text" : "f(t)" , "style" : {"fontSize" : "22px" , "color" : INK }},
85+ "labels" : {"style" : {"fontSize" : "18px" , "color" : INK_SOFT }},
86+ "lineColor" : INK_SOFT ,
87+ "tickColor" : INK_SOFT ,
88+ "gridLineColor" : GRID ,
8389 "tickInterval" : 1 ,
8490}
8591
86- # Colors for species (colorblind-safe)
87- colors = ["#306998" , "#FFD43B" , "#9467BD" ]
88-
89- # Legend styling - positioned inside chart area to avoid clipping
9092chart .options .legend = {
9193 "enabled" : True ,
92- "itemStyle" : {"fontSize" : "36px " , "fontWeight " : "bold" },
93- "symbolWidth" : 60 ,
94- "symbolHeight" : 4 ,
94+ "itemStyle" : {"fontSize" : "18px " , "color " : INK_SOFT },
95+ "symbolWidth" : 30 ,
96+ "symbolHeight" : 2 ,
9597 "align" : "right" ,
9698 "verticalAlign" : "top" ,
9799 "layout" : "vertical" ,
98100 "x" : - 50 ,
99- "y" : 80 ,
100- "itemDistance" : 20 ,
101- "itemMarginTop" : 10 ,
102- "backgroundColor" : "rgba(255,255,255,0.9)" ,
101+ "y" : 50 ,
102+ "backgroundColor" : ELEVATED_BG ,
103103 "borderWidth" : 1 ,
104- "borderColor" : "#cccccc" ,
104+ "borderColor" : INK_SOFT ,
105105 "padding" : 15 ,
106106}
107107
108- # Plot options for transparency
109108chart .options .plot_options = {
110109 "line" : {"lineWidth" : 3 , "marker" : {"enabled" : False }, "animation" : False },
111110 "series" : {"animation" : False },
112111}
113112
114- # Generate curves for each observation (sample 20 per species for clarity)
115113np .random .seed (42 )
116114samples_per_species = 20
117115
@@ -124,36 +122,36 @@ def andrews_curve(x, t):
124122 curve_values = andrews_curve (species_X [idx ], t )
125123 data_points = [[float (t [j ]), float (curve_values [j ])] for j in range (len (t ))]
126124
127- series = LineSeries ()
125+ series = SplineSeries ()
128126 series .data = data_points
129127 series .name = species_names [species_idx ]
130- series .color = colors [species_idx ]
128+ series .color = OKABE_ITO [species_idx ]
131129 series .opacity = 0.5
132- series .show_in_legend = i == 0 # Only show first curve in legend
130+ series .show_in_legend = i == 0
133131 series .line_width = 2
134132
135133 chart .add_series (series )
136134
137- # Download Highcharts JS
138- highcharts_url = "https://code.highcharts.com/highcharts.js"
135+ highcharts_url = "https://cdn.jsdelivr.net/npm/highcharts@latest/highcharts.js"
139136with urllib .request .urlopen (highcharts_url , timeout = 30 ) as response :
140137 highcharts_js = response .read ().decode ("utf-8" )
141138
142- # Generate HTML with inline script
143139html_str = chart .to_js_literal ()
144140html_content = f"""<!DOCTYPE html>
145141<html>
146142<head>
147143 <meta charset="utf-8">
148144 <script>{ highcharts_js } </script>
149145</head>
150- <body style="margin:0;">
146+ <body style="margin:0; background: { PAGE_BG } ; ">
151147 <div id="container" style="width: 4800px; height: 2700px;"></div>
152148 <script>{ html_str } </script>
153149</body>
154150</html>"""
155151
156- # Write temp HTML and capture screenshot
152+ with open (f"plot-{ THEME } .html" , "w" , encoding = "utf-8" ) as f :
153+ f .write (html_content )
154+
157155with tempfile .NamedTemporaryFile (mode = "w" , suffix = ".html" , delete = False , encoding = "utf-8" ) as f :
158156 f .write (html_content )
159157 temp_path = f .name
@@ -163,19 +161,12 @@ def andrews_curve(x, t):
163161chrome_options .add_argument ("--no-sandbox" )
164162chrome_options .add_argument ("--disable-dev-shm-usage" )
165163chrome_options .add_argument ("--disable-gpu" )
166- chrome_options .add_argument ("--window-size=4900,2800 " )
164+ chrome_options .add_argument ("--window-size=4800,2700 " )
167165
168166driver = webdriver .Chrome (options = chrome_options )
169167driver .get (f"file://{ temp_path } " )
170168time .sleep (5 )
171-
172- # Screenshot the chart element for exact dimensions
173- container = driver .find_element ("id" , "container" )
174- container .screenshot ("plot.png" )
169+ driver .save_screenshot (f"plot-{ THEME } .png" )
175170driver .quit ()
176171
177172Path (temp_path ).unlink ()
178-
179- # Also save HTML for interactive version
180- with open ("plot.html" , "w" , encoding = "utf-8" ) as f :
181- f .write (html_content )
0 commit comments