|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | 5 | import os |
| 6 | +from typing import List, Tuple, Sequence, Optional, Union |
| 7 | +from io import StringIO |
| 8 | +import numpy as np |
| 9 | +import plotext as plt |
| 10 | +from rich.console import Console |
| 11 | +from rich.table import Table |
| 12 | +from loguru import logger |
6 | 13 | from abc import ABC, abstractmethod |
7 | 14 | from io import StringIO |
8 | 15 | from pathlib import Path |
@@ -80,10 +87,10 @@ def take_picture(self, focus: Focus) -> Image: |
80 | 87 |
|
81 | 88 | def _log_optimization_history(history: Sequence[Tuple[float, float]]) -> None: |
82 | 89 | """ |
83 | | - Log the optimization history as a formatted table using Rich. |
| 90 | + Log the optimization history as a formatted table and plot using Rich and Plotext. |
84 | 91 |
|
85 | 92 | Args: |
86 | | - history: List of (focus, score) tuples to be displayed in the table |
| 93 | + history: List of (focus, score) tuples to be displayed in the table and plot |
87 | 94 | """ |
88 | 95 | if not history: |
89 | 96 | logger.warning("No history data to display") |
@@ -115,6 +122,39 @@ def _log_optimization_history(history: Sequence[Tuple[float, float]]) -> None: |
115 | 122 | # Log the table using loguru |
116 | 123 | logger.info("\n" + table_output.getvalue()) |
117 | 124 |
|
| 125 | + |
| 126 | + # Create a terminal plot |
| 127 | + try: |
| 128 | + # Extract focus and score values |
| 129 | + focus_vals = [h[0] for h in history] |
| 130 | + scores = [h[1] for h in history] |
| 131 | + |
| 132 | + # Sort by focus for better visualization |
| 133 | + sorted_pairs = sorted(zip(focus_vals, scores), key=lambda x: x[0]) |
| 134 | + focus_vals, scores = zip(*sorted_pairs) |
| 135 | + |
| 136 | + # Create the plot |
| 137 | + plt.clear_figure() |
| 138 | + plt.plot(focus_vals, scores, marker="dot", label="Score") |
| 139 | + plt.title("Focus Optimization History") |
| 140 | + plt.xlabel("Focus Value") |
| 141 | + plt.ylabel("Score") |
| 142 | + plt.grid(True) |
| 143 | + |
| 144 | + # Add markers for all points |
| 145 | + plt.scatter(focus_vals, scores, marker="dot") |
| 146 | + |
| 147 | + # Find and highlight the best focus |
| 148 | + best_idx = np.argmax(scores) |
| 149 | + plt.scatter([focus_vals[best_idx]], [scores[best_idx]], marker="*", color="red") |
| 150 | + |
| 151 | + # Show the plot |
| 152 | + logger.info("\nFocus Optimization Plot:") |
| 153 | + plt.show() |
| 154 | + |
| 155 | + except Exception as e: |
| 156 | + logger.warning(f"Failed to create terminal plot: {str(e)}") |
| 157 | + |
118 | 158 |
|
119 | 159 | def optimize_focus( |
120 | 160 | camera: "Camera", |
|
0 commit comments