Repository: optuna/optuna
Pull request: Public APIs for checking visualization availability
Fixes https://github.com/pfnet/optuna/issues/603.

There might be better names out there for the introduced APIs so am more than happy for suggestions.

By the way, I'm not sure if this issue applies to our integration submodules.

Problem statement:
Visualization availability check is not possible without actually trying to plot
The plot function is expected to be called towards the end of the script after a possibly time consuming study has been completed. However, since the plotting library plotly is not requires by Optuna, the script may encounter an error when calling the plot function. What would be better would be to catch the error earlier in the script.

It could be useful to at least expose a plotly availability check function as a public API to allow this.

Hints from issue discussion:

Commit message: Add is_available to docs

Patch to review:
diff --git a/docs/source/reference/visualization.rst b/docs/source/reference/visualization.rst
index 3171887b211..16895fd816a 100644
--- a/docs/source/reference/visualization.rst
+++ b/docs/source/reference/visualization.rst
@@ -13,3 +13,5 @@ Visualization
 .. autofunction:: plot_parallel_coordinate
 
 .. autofunction:: plot_slice
+
+.. autofunction:: is_available
diff --git a/optuna/visualization.py b/optuna/visualization.py
index 6fcfdd10326..ba50eb16851 100644
--- a/optuna/visualization.py
+++ b/optuna/visualization.py
@@ -29,6 +29,17 @@
     _available = False
 
 
+def is_available():
+    # type: () -> bool
+    """Returns whether visualization is available or not.
+
+    Returns:
+        ``True`` is visualization is available, ``False`` otherwise.
+    """
+
+    return _available
+
+
 def plot_intermediate_values(study):
     # type: (Study) -> None
     """Plot intermediate values of all trials in a study.
@@ -532,7 +543,7 @@ def _generate_slice_subplot(study, trials, param):
 def _check_plotly_availability():
     # type: () -> None
 
-    if not _available:
+    if not is_available():
         raise ImportError(
             'Plotly is not available. Please install plotly to use this feature. '
             'Plotly can be installed by executing `$ pip install plotly`. '
diff --git a/tests/test_visualization.py b/tests/test_visualization.py
index 49cf88ab910..79e43e6a765 100644
--- a/tests/test_visualization.py
+++ b/tests/test_visualization.py
@@ -3,6 +3,7 @@
 from optuna.distributions import UniformDistribution
 from optuna.study import create_study
 from optuna.trial import Trial  # NOQA
+from optuna import visualization
 from optuna.visualization import _get_contour_plot
 from optuna.visualization import _get_intermediate_plot
 from optuna.visualization import _get_optimization_history_plot
@@ -308,3 +309,20 @@ def fail_objective(_):
     study.optimize(fail_objective, n_trials=1)
     figure = _get_slice_plot(study)
     assert len(figure.data) == 0
+
+
+def _is_plotly_available():
+    # type: () -> bool
+
+    try:
+        import plotly  # NOQA
+        available = True
+    except Exception:
+        available = False
+    return available
+
+
+def test_visualization_is_available():
+    # type: () -> None
+
+    assert visualization.is_available() == _is_plotly_available()


Code review comments:
diff_hunk: @@ -29,6 +29,17 @@
     _available = False
 
 
+def is_available():
+    # type: () -> bool
+    """Returns whether visualization is available or not.
+
+    Returns:
+        ``True`` is visualization is available, ``False`` otherwise.
path: optuna/visualization.py
text: @user1:
typo?
```suggestion
        ``True`` if visualization is available, ``False`` otherwise.
```

@author:
You're right, thank you. Applied the suggestion.