diff --git a/optuna/visualization/_contour.py b/optuna/visualization/_contour.py index a71607b32d..44904c0425 100644 --- a/optuna/visualization/_contour.py +++ b/optuna/visualization/_contour.py @@ -4,6 +4,7 @@ from typing import Any from typing import Callable from typing import NamedTuple +import warnings import numpy as np @@ -208,6 +209,15 @@ def _get_contour_subplot( x_indices = info.xaxis.indices y_indices = info.yaxis.indices + if len(x_indices) < 2 or len(y_indices) < 2: + return go.Contour(), go.Scatter(), go.Scatter() + if len(info.z_values) == 0: + warnings.warn( + f"Contour plot will not be displayed because `{info.xaxis.name}` and " + f"`{info.yaxis.name}` cannot co-exist in `trial.params`." + ) + return go.Contour(), go.Scatter(), go.Scatter() + feasible = _PlotValues([], []) infeasible = _PlotValues([], []) @@ -227,9 +237,6 @@ def _get_contour_subplot( z_values[xys[:, 1], xys[:, 0]] = zs - if len(x_indices) < 2 or len(y_indices) < 2: - return go.Contour(), go.Scatter(), go.Scatter() - contour = go.Contour( x=x_indices, y=y_indices, diff --git a/tests/visualization_tests/test_visualizations.py b/tests/visualization_tests/test_visualizations.py index 71cac17e77..a6e7439ce5 100644 --- a/tests/visualization_tests/test_visualizations.py +++ b/tests/visualization_tests/test_visualizations.py @@ -87,10 +87,6 @@ def test_visualizations_with_single_objectives( study = optuna.create_study(sampler=optuna.samplers.RandomSampler()) study.optimize(objective_func, n_trials=20) - # TODO(c-bata): Fix a bug to remove `pytest.xfail`. - if plot_func is plot_contour and objective_func is objective_single_dynamic_with_categorical: - pytest.xfail("There is a bug that IndexError is raised in plot_contour") - # TODO(c-bata): Fix a bug to remove `pytest.xfail`. if plot_func is matplotlib_plot_rank and objective_func is objective_single_none_categorical: pytest.xfail("There is a bug that TypeError is raised in matplotlib.plot_rank")