Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions example_notebooks/plotting_metrics.ipynb

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions src/paretobench/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class Metric(BaseModel):
def name(self):
raise NotImplementedError

def get_plot_label(self) -> str:
"""Returns label for y axis of plots with the metric."""
raise NotImplementedError

def __call__(self, pop: Population, problem: Union[Problem, str]):
"""
Evaluate the metric.
Expand Down Expand Up @@ -78,6 +82,9 @@ def __call__(self, pop: Population, problem: Union[Problem, str]):
def name(self):
return "igd"

def get_plot_label(self) -> str:
return "IGD"


class Hypervolume(Metric):
"""
Expand Down Expand Up @@ -157,6 +164,9 @@ def __call__(self, pop: Population, problem: Union[Problem, str]):
def name(self):
return "hypervolume"

def get_plot_label(self) -> str:
return "Hypervolume"


@dataclass
class EvalMetricsJob:
Expand Down
2 changes: 2 additions & 0 deletions src/paretobench/plotting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
history_obj_scatter,
history_dvar_pairs,
)
from .metrics import plot_metric_history

__all__ = [
"population_dvar_pairs",
Expand All @@ -16,4 +17,5 @@
"history_obj_animation",
"history_obj_scatter",
"history_dvar_pairs",
"plot_metric_history",
]
57 changes: 57 additions & 0 deletions src/paretobench/plotting/metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import matplotlib.pyplot as plt
from typing import Literal

from paretobench.containers import History
from paretobench.metrics import Metric, eval_metrics


def plot_metric_history(
hist: History,
metric: Metric,
x_axis: Literal["fevals", "generation"] = "fevals",
fig: plt.Figure | None = None,
ax: plt.Axes | None = None,
):
"""
Evaluate and plot evolution of a metric across the populations within a `History` object.

Parameters
----------
hist : History
The genetic algorithm history to plot
metric : Metric
The metric to evaluate and plot
x_axis : Literal["fevals", "generation"]
What value to use for x-axis in plot
fig : plt.Figure | None
Matplotlib figure if plotting to user-provided figure (must also specify axis)
ax : plt.Axes | None
Matplotlib axis to place plot into (must also specify figure)

Returns
-------
plt.Figure, plt.Axes
The matplotlib figure and axis the data was plotted to
"""
# Calculate the metrics from the history object
df = eval_metrics(hist, metric)

if fig is None or ax is None:
fig, ax = plt.subplots()

# Grab the x values and axis label
if x_axis == "fevals":
x_vals = df["fevals"]
xlabel = "Function Evaluations"
elif x_axis == "generation":
x_vals = df["pop_idx"]
xlabel = "Generation"
else:
raise ValueError(f"Unrecognized value for `x_axis`: {x_vals}")

# Plot the data
ax.plot(x_vals, df[metric.name])
ax.set_xlabel(xlabel)
ax.set_ylabel(metric.get_plot_label())

return fig, ax
Loading