class_docstr: Object that can be rendered by HiPlot. It essential contains a list of metrics, but also some options on how to render it.
  
  See :meth:`Experiment.display` to display an :class:`Experiment` in an ipython notebook.
  
  :ivar datapoints: All the measurements we have. One datapoint corresponds to one line in the parallel plot and to one line in the table.
  :ivar parameters_definition: Characteristics of the columns (ordering, type, etc...)
  :ivar colormap: Colormap to use
  :ivar colorby: Default column to color by
  :ivar weightcolumn: If rows have different weights, use this column as the weight (default to 1 if not specified)
  :ivar enabledDisplays: Ordered displays to enable (by default all are enabled)
  
  :Example:
  
  .. code-block:: python
  
      import hiplot as hip
      data = [{'param': 1, 'loss': 10, 'hidden_field': 'value1', 'c': 'red'},
          {'param': 2, 'loss': 5, 'hidden_field': 'value2', 'c': 'black'}]
      exp = hip.Experiment.from_iterable(data)
docstr: Creates a HiPlot experiment from a Optuna Study.
  
  :param study: Optuna Study
docstr_tok: ["Creates","a","HiPlot","experiment","from","a","Optuna","Study",".",":","param","study",":","Optuna","Study"]
code: def from_optuna(
      study: "optuna.study.Study",
  ) -> (
      "Experiment"
  ):  # No type hint to avoid having optuna as an additional dependency
      """
      Creates a HiPlot experiment from a Optuna Study.
  
      :param study: Optuna Study
      """
  
      # Create a list of dictionary objects using study trials
      # All parameters are taken using params.copy()
      # pylint: disable=redefined-outer-name
      import optuna
  
      hyper_opt_data = []
      for each_trial in study.get_trials(
          states=(optuna.trial.TrialState.COMPLETE,)
      ):
          trial_params = {}
          # This checks if the trial was fully completed
          # the value will be None if the trial was interrupted halfway (e.g. via KeyboardInterrupt)
          if not each_trial.values:
              continue
          num_objectives = len(each_trial.values)
  
          if num_objectives == 1:
              # name = value, as it could be RMSE / accuracy, or any value that the user selects for tuning
              trial_params["value"] = each_trial.value
          else:
              for objective_id, value in enumerate(each_trial.values):
                  trial_params[f"value_{objective_id}"] = value
  
          trial_params["uid"] = each_trial.number
          trial_params.update(each_trial.params.copy())
          hyper_opt_data.append(trial_params)
      experiment = Experiment.from_iterable(hyper_opt_data)
  
      return experiment
  
imports: import csv
  import uuid
  import json
  import codecs
  import warnings
  from abc import ABCMeta, abstractmethod
  from enum import Enum
  from collections import defaultdict
  from pathlib import Path
  import typing
label_desc: Use image node_id 18 for calling the Experiment obj's underlying member method code with example usage: obj.from_optuna(study) and returns: experiment