#!/usr/bin/env python3 """ Create side-by-side comparison of best circle packing solutions. """ from pathlib import Path from PIL import Image, ImageDraw, ImageFont import sys def create_comparison(with_path, without_path, output_path): """Create side-by-side comparison with labels.""" # Load images img_with = Image.open(with_path) img_without = Image.open(without_path) # Resize if needed (make them same height) target_height = 800 aspect_with = img_with.width / img_with.height aspect_without = img_without.width / img_without.height img_with = img_with.resize((int(target_height * aspect_with), target_height), Image.LANCZOS) img_without = img_without.resize((int(target_height * aspect_without), target_height), Image.LANCZOS) # Create new image with padding padding = 40 label_height = 80 total_width = img_with.width + img_without.width + padding * 3 total_height = target_height + label_height + padding * 2 # Create white background combined = Image.new('RGB', (total_width, total_height), 'white') # Paste images combined.paste(img_with, (padding, label_height + padding)) combined.paste(img_without, (img_with.width + padding * 2, label_height + padding)) # Add labels draw = ImageDraw.Draw(combined) # Try to use a nice font, fallback to default try: font_title = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 28) font_score = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 20) except: font_title = ImageFont.load_default() font_score = ImageFont.load_default() # Labels label_with = "WITH Vision" label_without = "WITHOUT Vision" score_with = "Score: 2.5786 (Gen 95)" score_without = "Score: 2.5507 (Gen 97)" # Calculate text positions (centered above each image) with_center_x = padding + img_with.width // 2 without_center_x = img_with.width + padding * 2 + img_without.width // 2 # Draw labels with background def draw_label(text, x, y, font, color): bbox = draw.textbbox((x, y), text, font=font, anchor="mm") draw.rectangle(bbox, fill='white') draw.text((x, y), text, fill=color, font=font, anchor="mm") # Main title title = "Best Circle Packing Solutions Comparison" title_x = total_width // 2 try: font_main = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 36) except: font_main = font_title draw_label(title, title_x, padding // 2 + 5, font_main, 'black') # WITH Vision labels draw_label(label_with, with_center_x, label_height // 2 + 5, font_title, '#2E86AB') draw_label(score_with, with_center_x, label_height - 15, font_score, '#555555') # WITHOUT Vision labels draw_label(label_without, without_center_x, label_height // 2 + 5, font_title, '#A23B72') draw_label(score_without, without_center_x, label_height - 15, font_score, '#555555') # Add difference note diff_text = "Difference: +1.1% (WITH Vision)" draw_label(diff_text, total_width // 2, total_height - padding // 2, font_score, '#008800') # Save combined.save(output_path, quality=95) print(f"✅ Created comparison: {output_path}") def main(): base_dir = Path(__file__).parent.parent / "examples" / "circle_packing" with_path = base_dir / "results_circle_packing_WITH_vision_20260114_065819" / \ "best" / "results" / "packing_viz.png" without_path = base_dir / "results_circle_packing_WITHOUT_vision_20260114_070110" / \ "best" / "results" / "packing_viz.png" output_dir = Path(__file__).parent / "plots" output_dir.mkdir(exist_ok=True) output_path = output_dir / "best_solutions_comparison.png" if not with_path.exists(): print(f"❌ WITH vision image not found: {with_path}") return if not without_path.exists(): print(f"❌ WITHOUT vision image not found: {without_path}") return print("🎨 Creating side-by-side comparison...") create_comparison(with_path, without_path, output_path) print(f"📊 Output: {output_path}") if __name__ == "__main__": main()