1+ import argparse
12import os
3+ import sys
24from typing import Iterable
35
46import numpy as np
@@ -70,12 +72,13 @@ def save_plt_to_file(solutions: Iterable, filename: str, out_dir: str = "results
7072 pass
7173
7274 elif n_obj == 3 :
75+ axis_labels = [f"f{ i + 1 } " for i in range (n_obj )]
7376 fig = plt .figure (figsize = (6 , 6 ))
7477 ax = fig .add_subplot (111 , projection = "3d" )
7578 ax .scatter (arr [:, 0 ], arr [:, 1 ], arr [:, 2 ], s = 8 , c = "C0" , alpha = 0.8 )
76- ax .set_xlabel ("f1" )
77- ax .set_ylabel ("f2" )
78- ax .set_zlabel ("f3" )
79+ ax .set_xlabel (axis_labels [ 0 ] )
80+ ax .set_ylabel (axis_labels [ 1 ] )
81+ ax .set_zlabel (axis_labels [ 2 ] )
7982 ax .set_title (f"{ filename } approximation front (3D)" )
8083 plt .tight_layout ()
8184 fig .savefig (png_path , dpi = 200 )
@@ -86,8 +89,9 @@ def save_plt_to_file(solutions: Iterable, filename: str, out_dir: str = "results
8689 try :
8790 import pandas as pd
8891
89- df = pd .DataFrame (arr , columns = [f"f{ i + 1 } " for i in range (n_obj )])
90- figly = px .scatter_3d (df , x = df .columns [0 ], y = df .columns [1 ], z = df .columns [2 ], title = f"{ filename } approximation front (3D)" )
92+ df = pd .DataFrame (arr , columns = axis_labels )
93+ figly = px .scatter_3d (df , x = axis_labels [0 ], y = axis_labels [1 ], z = axis_labels [2 ], title = f"{ filename } approximation front (3D)" )
94+ figly .update_layout (scene = dict (xaxis_title = axis_labels [0 ], yaxis_title = axis_labels [1 ], zaxis_title = axis_labels [2 ]))
9195 html_path = os .path .join (out_dir , f"{ filename } _front.html" )
9296 pyoff .plot (figly , filename = html_path , auto_open = False )
9397 except Exception :
@@ -122,3 +126,74 @@ def save_plt_to_file(solutions: Iterable, filename: str, out_dir: str = "results
122126 pass
123127
124128 return png_path
129+
130+
131+ def _read_numeric_csv (csv_path : str ) -> np .ndarray :
132+ """Load numeric columns from a CSV file into a NumPy array."""
133+ try :
134+ import pandas as pd # type: ignore
135+
136+ df = pd .read_csv (csv_path )
137+ numeric_df = df .select_dtypes (include = [np .number ])
138+ if numeric_df .empty :
139+ raise ValueError ("No numeric columns found in CSV" )
140+ arr = numeric_df .to_numpy ()
141+ if arr .ndim == 1 :
142+ arr = arr .reshape (- 1 , 1 )
143+ return arr
144+ except Exception :
145+ pass
146+
147+ for skip_header in (0 , 1 ):
148+ data = np .genfromtxt (csv_path , delimiter = "," , skip_header = skip_header )
149+ if data .size == 0 or (isinstance (data , float ) and np .isnan (data )):
150+ continue
151+ if data .ndim == 0 :
152+ continue
153+ if data .ndim == 1 :
154+ data = data .reshape (- 1 , 1 )
155+ data = np .asarray (data , dtype = float )
156+ if data .ndim > 1 :
157+ data = data [~ np .isnan (data ).all (axis = 1 )]
158+ if data .size == 0 or np .isnan (data ).all ():
159+ continue
160+ return data
161+
162+ raise ValueError (f"Could not read numeric data from { csv_path } " )
163+
164+
165+ def _cli () -> None :
166+ """Entry point for plotting approximation fronts from CSV files."""
167+ parser = argparse .ArgumentParser (description = "Generate approximation front plots from a numeric CSV file." )
168+ parser .add_argument ("csv_file" , help = "Path to a CSV file containing numeric columns to plot." )
169+ parser .add_argument ("--out-dir" , default = "results" , help = "Directory where output files will be written (default: results)." )
170+ parser .add_argument ("--base-name" , help = "Base name for generated files (defaults to CSV filename without extension)." )
171+ parser .add_argument ("--html" , action = "store_true" , help = "Also generate an interactive Plotly HTML if available." )
172+ args = parser .parse_args ()
173+
174+ base_name = args .base_name or os .path .splitext (os .path .basename (args .csv_file ))[0 ]
175+
176+ try :
177+ front = _read_numeric_csv (args .csv_file )
178+ except Exception as ex :
179+ print (f"Error reading CSV '{ args .csv_file } ': { ex } " , file = sys .stderr )
180+ sys .exit (1 )
181+
182+ try :
183+ png_path = save_plt_to_file (front , base_name , out_dir = args .out_dir , html_plotly = args .html )
184+ except Exception as ex :
185+ print (f"Error generating plot: { ex } " , file = sys .stderr )
186+ sys .exit (1 )
187+
188+ print (f"PNG saved to: { png_path } " )
189+ if args .html :
190+ if not _PLOTLY_AVAILABLE :
191+ print ("Plotly not available; HTML file not generated." , file = sys .stderr )
192+ else :
193+ html_path = os .path .join (args .out_dir , f"{ base_name } _front.html" )
194+ if os .path .isfile (html_path ):
195+ print (f"HTML saved to: { html_path } " )
196+
197+
198+ if __name__ == "__main__" :
199+ _cli ()
0 commit comments