prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Axis labels of parallel coordinate plots overlap if the parameter names are long.
  As you can see in the following image, axis labels overlap when parameter names are too long. I think we can solve this issue if we limit the maximum length of the labels and/or tilt the labels.
  
  ![newplot (39)](https://user-images.githubusercontent.com/3255979/66977250-19efd780-f0e0-11e9-87ba-a6616083da31.png)
  
  **Conditions**
  - Optuna version: 0.17.1
  - Python version: 3.7.2
  - OS: macOS 10.13
  
  **Code to reproduce**
  
  ```python
  import optuna
  
  def objective(trial):
      x = trial.suggest_uniform('x' * 100, -10, 10)
      y = trial.suggest_uniform('y' * 100, -10, 10)
      return x - y
  
  study = optuna.create_study()
  study.optimize(objective, n_trials=20)
  
  optuna.visualization.plot_parallel_coordinate(study)
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `optuna/visualization/parallel_coordinate.py`
  Content:
  ```
  1 from collections import defaultdict
  2 
  3 from optuna.logging import get_logger
  4 from optuna.structs import StudyDirection
  5 from optuna.structs import TrialState
  6 from optuna import type_checking
  7 from optuna.visualization.utils import _check_plotly_availability
  8 from optuna.visualization.utils import is_available
  9 
  10 if type_checking.TYPE_CHECKING:
  11     from typing import Any  # NOQA
  12     from typing import DefaultDict  # NOQA
  13     from typing import Dict  # NOQA
  14     from typing import List  # NOQA
  15     from typing import Optional  # NOQA
  16 
  17     from optuna.study import Study  # NOQA
  18 
  19 if is_available():
  20     from optuna.visualization.plotly_imports import go
  21 
  22 logger = get_logger(__name__)
  23 
  24 
  25 def plot_parallel_coordinate(study, params=None):
  26     # type: (Study, Optional[List[str]]) -> go.Figure
  27     """Plot the high-dimentional parameter relationships in a study.
  28 
  29     Note that, If a parameter contains missing values, a trial with missing values is not plotted.
  30 
  31     Example:
  32 
  33         The following code snippet shows how to plot the high-dimentional parameter relationships.
  34 
  35         .. testcode::
  36 
  37             import optuna
  38 
  39             def objective(trial):
  40                 x = trial.suggest_uniform('x', -100, 100)
  41                 y = trial.suggest_categorical('y', [-1, 0, 1])
  42                 return x ** 2 + y
  43 
  44             study = optuna.create_study()
  45             study.optimize(objective, n_trials=10)
  46 
  47             optuna.visualization.plot_parallel_coordinate(study, params=['x', 'y'])
  48 
  49         .. raw:: html
  50 
  51             <iframe src="../_static/plot_parallel_coordinate.html"
  52              width="100%" height="500px" frameborder="0">
  53             </iframe>
  54 
  55     Args:
  56         study:
  57             A :class:`~optuna.study.Study` object whose trials are plotted for their objective
  58             values.
  59         params:
  60             Parameter list to visualize. The default is all parameters.
  61 
  62     Returns:
  63         A :class:`plotly.graph_objs.Figure` object.
  64     """
  65 
  66     _check_plotly_availability()
  67     return _get_parallel_coordinate_plot(study, params)
  68 
  69 
  70 def _get_parallel_coordinate_plot(study, params=None):
  71     # type: (Study, Optional[List[str]]) -> go.Figure
  72 
  73     layout = go.Layout(title="Parallel Coordinate Plot",)
  74 
  75     trials = [trial for trial in study.trials if trial.state == TrialState.COMPLETE]
  76 
  77     if len(trials) == 0:
  78         logger.warning("Your study does not have any completed trials.")
  79         return go.Figure(data=[], layout=layout)
  80 
  81     all_params = {p_name for t in trials for p_name in t.params.keys()}
  82     if params is not None:
  83         for input_p_name in params:
  84             if input_p_name not in all_params:
  85                 ValueError("Parameter {} does not exist in your study.".format(input_p_name))
  86         all_params = set(params)
  87     sorted_params = sorted(list(all_params))
  88 
  89     dims = [
  90         {
  91             "label": "Objective Value",
  92             "values": tuple([t.value for t in trials]),
  93             "range": (min([t.value for t in trials]), max([t.value for t in trials])),
  94         }
  95     ]  # type: List[Dict[str, Any]]
  96     for p_name in sorted_params:
  97         values = []
  98         for t in trials:
  99             if p_name in t.params:
  100                 values.append(t.params[p_name])
  101         is_categorical = False
  102         try:
  103             tuple(map(float, values))
  104         except (TypeError, ValueError):
  105             vocab = defaultdict(lambda: len(vocab))  # type: DefaultDict[str, int]
  106             values = [vocab[v] for v in values]
  107             is_categorical = True
  108         dim = {"label": p_name, "values": tuple(values), "range": (min(values), max(values))}
  109         if is_categorical:
  110             dim["tickvals"] = list(range(len(vocab)))
  111             dim["ticktext"] = list(sorted(vocab.items(), key=lambda x: x[1]))
  112         dims.append(dim)
  113 
  114     traces = [
  115         go.Parcoords(
  116             dimensions=dims,
  117             line={
  118                 "color": dims[0]["values"],
  119                 "colorscale": "blues",
  120                 "colorbar": {"title": "Objective Value"},
  121                 "showscale": True,
  122                 "reversescale": study.direction == StudyDirection.MINIMIZE,
  123             },
  124         )
  125     ]
  126 
  127     figure = go.Figure(data=traces, layout=layout)
  128 
  129     return figure
  130
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/optuna/visualization/parallel_coordinate.py b/optuna/visualization/parallel_coordinate.py
  --- a/optuna/visualization/parallel_coordinate.py
  +++ b/optuna/visualization/parallel_coordinate.py
  @@ -93,6 +93,7 @@
               "range": (min([t.value for t in trials]), max([t.value for t in trials])),
           }
       ]  # type: List[Dict[str, Any]]
  +
       for p_name in sorted_params:
           values = []
           for t in trials:
  @@ -105,7 +106,11 @@
               vocab = defaultdict(lambda: len(vocab))  # type: DefaultDict[str, int]
               values = [vocab[v] for v in values]
               is_categorical = True
  -        dim = {"label": p_name, "values": tuple(values), "range": (min(values), max(values))}
  +        dim = {
  +            "label": p_name if len(p_name) < 20 else "{}...".format(p_name[:17]),
  +            "values": tuple(values),
  +            "range": (min(values), max(values)),
  +        }  # type: Dict[str, object]
           if is_categorical:
               dim["tickvals"] = list(range(len(vocab)))
               dim["ticktext"] = list(sorted(vocab.items(), key=lambda x: x[1]))
  @@ -114,6 +119,8 @@
       traces = [
           go.Parcoords(
               dimensions=dims,
  +            labelangle=30,
  +            labelside="bottom",
               line={
                   "color": dims[0]["values"],
                   "colorscale": "blues",
  
verification_info: {"golden_diff": "diff --git a/optuna/visualization/parallel_coordinate.py b/optuna/visualization/parallel_coordinate.py\n--- a/optuna/visualization/parallel_coordinate.py\n+++ b/optuna/visualization/parallel_coordinate.py\n@@ -93,6 +93,7 @@\n             \"range\": (min([t.value for t in trials]), max([t.value for t in trials])),\n         }\n     ]  # type: List[Dict[str, Any]]\n+\n     for p_name in sorted_params:\n         values = []\n         for t in trials:\n@@ -105,7 +106,11 @@\n             vocab = defaultdict(lambda: len(vocab))  # type: DefaultDict[str, int]\n             values = [vocab[v] for v in values]\n             is_categorical = True\n-        dim = {\"label\": p_name, \"values\": tuple(values), \"range\": (min(values), max(values))}\n+        dim = {\n+            \"label\": p_name if len(p_name) < 20 else \"{}...\".format(p_name[:17]),\n+            \"values\": tuple(values),\n+            \"range\": (min(values), max(values)),\n+        }  # type: Dict[str, object]\n         if is_categorical:\n             dim[\"tickvals\"] = list(range(len(vocab)))\n             dim[\"ticktext\"] = list(sorted(vocab.items(), key=lambda x: x[1]))\n@@ -114,6 +119,8 @@\n     traces = [\n         go.Parcoords(\n             dimensions=dims,\n+            labelangle=30,\n+            labelside=\"bottom\",\n             line={\n                 \"color\": dims[0][\"values\"],\n                 \"colorscale\": \"blues\",\n", "issue": "Axis labels of parallel coordinate plots overlap if the parameter names are long.\nAs you can see in the following image, axis labels overlap when parameter names are too long. I think we can solve this issue if we limit the maximum length of the labels and/or tilt the labels.\r\n\r\n![newplot (39)](https://user-images.githubusercontent.com/3255979/66977250-19efd780-f0e0-11e9-87ba-a6616083da31.png)\r\n\r\n**Conditions**\r\n- Optuna version: 0.17.1\r\n- Python version: 3.7.2\r\n- OS: macOS 10.13\r\n\r\n**Code to reproduce**\r\n\r\n```python\r\nimport optuna\r\n\r\ndef objective(trial):\r\n    x = trial.suggest_uniform('x' * 100, -10, 10)\r\n    y = trial.suggest_uniform('y' * 100, -10, 10)\r\n    return x - y\r\n\r\nstudy = optuna.create_study()\r\nstudy.optimize(objective, n_trials=20)\r\n\r\noptuna.visualization.plot_parallel_coordinate(study)\r\n```\n", "before_files": [{"content": "from collections import defaultdict\n\nfrom optuna.logging import get_logger\nfrom optuna.structs import StudyDirection\nfrom optuna.structs import TrialState\nfrom optuna import type_checking\nfrom optuna.visualization.utils import _check_plotly_availability\nfrom optuna.visualization.utils import is_available\n\nif type_checking.TYPE_CHECKING:\n    from typing import Any  # NOQA\n    from typing import DefaultDict  # NOQA\n    from typing import Dict  # NOQA\n    from typing import List  # NOQA\n    from typing import Optional  # NOQA\n\n    from optuna.study import Study  # NOQA\n\nif is_available():\n    from optuna.visualization.plotly_imports import go\n\nlogger = get_logger(__name__)\n\n\ndef plot_parallel_coordinate(study, params=None):\n    # type: (Study, Optional[List[str]]) -> go.Figure\n    \"\"\"Plot the high-dimentional parameter relationships in a study.\n\n    Note that, If a parameter contains missing values, a trial with missing values is not plotted.\n\n    Example:\n\n        The following code snippet shows how to plot the high-dimentional parameter relationships.\n\n        .. testcode::\n\n            import optuna\n\n            def objective(trial):\n                x = trial.suggest_uniform('x', -100, 100)\n                y = trial.suggest_categorical('y', [-1, 0, 1])\n                return x ** 2 + y\n\n            study = optuna.create_study()\n            study.optimize(objective, n_trials=10)\n\n            optuna.visualization.plot_parallel_coordinate(study, params=['x', 'y'])\n\n        .. raw:: html\n\n            <iframe src=\"../_static/plot_parallel_coordinate.html\"\n             width=\"100%\" height=\"500px\" frameborder=\"0\">\n            </iframe>\n\n    Args:\n        study:\n            A :class:`~optuna.study.Study` object whose trials are plotted for their objective\n            values.\n        params:\n            Parameter list to visualize. The default is all parameters.\n\n    Returns:\n        A :class:`plotly.graph_objs.Figure` object.\n    \"\"\"\n\n    _check_plotly_availability()\n    return _get_parallel_coordinate_plot(study, params)\n\n\ndef _get_parallel_coordinate_plot(study, params=None):\n    # type: (Study, Optional[List[str]]) -> go.Figure\n\n    layout = go.Layout(title=\"Parallel Coordinate Plot\",)\n\n    trials = [trial for trial in study.trials if trial.state == TrialState.COMPLETE]\n\n    if len(trials) == 0:\n        logger.warning(\"Your study does not have any completed trials.\")\n        return go.Figure(data=[], layout=layout)\n\n    all_params = {p_name for t in trials for p_name in t.params.keys()}\n    if params is not None:\n        for input_p_name in params:\n            if input_p_name not in all_params:\n                ValueError(\"Parameter {} does not exist in your study.\".format(input_p_name))\n        all_params = set(params)\n    sorted_params = sorted(list(all_params))\n\n    dims = [\n        {\n            \"label\": \"Objective Value\",\n            \"values\": tuple([t.value for t in trials]),\n            \"range\": (min([t.value for t in trials]), max([t.value for t in trials])),\n        }\n    ]  # type: List[Dict[str, Any]]\n    for p_name in sorted_params:\n        values = []\n        for t in trials:\n            if p_name in t.params:\n                values.append(t.params[p_name])\n        is_categorical = False\n        try:\n            tuple(map(float, values))\n        except (TypeError, ValueError):\n            vocab = defaultdict(lambda: len(vocab))  # type: DefaultDict[str, int]\n            values = [vocab[v] for v in values]\n            is_categorical = True\n        dim = {\"label\": p_name, \"values\": tuple(values), \"range\": (min(values), max(values))}\n        if is_categorical:\n            dim[\"tickvals\"] = list(range(len(vocab)))\n            dim[\"ticktext\"] = list(sorted(vocab.items(), key=lambda x: x[1]))\n        dims.append(dim)\n\n    traces = [\n        go.Parcoords(\n            dimensions=dims,\n            line={\n                \"color\": dims[0][\"values\"],\n                \"colorscale\": \"blues\",\n                \"colorbar\": {\"title\": \"Objective Value\"},\n                \"showscale\": True,\n                \"reversescale\": study.direction == StudyDirection.MINIMIZE,\n            },\n        )\n    ]\n\n    figure = go.Figure(data=traces, layout=layout)\n\n    return figure\n", "path": "optuna/visualization/parallel_coordinate.py"}], "after_files": [{"content": "from collections import defaultdict\n\nfrom optuna.logging import get_logger\nfrom optuna.structs import StudyDirection\nfrom optuna.structs import TrialState\nfrom optuna import type_checking\nfrom optuna.visualization.utils import _check_plotly_availability\nfrom optuna.visualization.utils import is_available\n\nif type_checking.TYPE_CHECKING:\n    from typing import Any  # NOQA\n    from typing import DefaultDict  # NOQA\n    from typing import Dict  # NOQA\n    from typing import List  # NOQA\n    from typing import Optional  # NOQA\n\n    from optuna.study import Study  # NOQA\n\nif is_available():\n    from optuna.visualization.plotly_imports import go\n\nlogger = get_logger(__name__)\n\n\ndef plot_parallel_coordinate(study, params=None):\n    # type: (Study, Optional[List[str]]) -> go.Figure\n    \"\"\"Plot the high-dimentional parameter relationships in a study.\n\n    Note that, If a parameter contains missing values, a trial with missing values is not plotted.\n\n    Example:\n\n        The following code snippet shows how to plot the high-dimentional parameter relationships.\n\n        .. testcode::\n\n            import optuna\n\n            def objective(trial):\n                x = trial.suggest_uniform('x', -100, 100)\n                y = trial.suggest_categorical('y', [-1, 0, 1])\n                return x ** 2 + y\n\n            study = optuna.create_study()\n            study.optimize(objective, n_trials=10)\n\n            optuna.visualization.plot_parallel_coordinate(study, params=['x', 'y'])\n\n        .. raw:: html\n\n            <iframe src=\"../_static/plot_parallel_coordinate.html\"\n             width=\"100%\" height=\"500px\" frameborder=\"0\">\n            </iframe>\n\n    Args:\n        study:\n            A :class:`~optuna.study.Study` object whose trials are plotted for their objective\n            values.\n        params:\n            Parameter list to visualize. The default is all parameters.\n\n    Returns:\n        A :class:`plotly.graph_objs.Figure` object.\n    \"\"\"\n\n    _check_plotly_availability()\n    return _get_parallel_coordinate_plot(study, params)\n\n\ndef _get_parallel_coordinate_plot(study, params=None):\n    # type: (Study, Optional[List[str]]) -> go.Figure\n\n    layout = go.Layout(title=\"Parallel Coordinate Plot\",)\n\n    trials = [trial for trial in study.trials if trial.state == TrialState.COMPLETE]\n\n    if len(trials) == 0:\n        logger.warning(\"Your study does not have any completed trials.\")\n        return go.Figure(data=[], layout=layout)\n\n    all_params = {p_name for t in trials for p_name in t.params.keys()}\n    if params is not None:\n        for input_p_name in params:\n            if input_p_name not in all_params:\n                ValueError(\"Parameter {} does not exist in your study.\".format(input_p_name))\n        all_params = set(params)\n    sorted_params = sorted(list(all_params))\n\n    dims = [\n        {\n            \"label\": \"Objective Value\",\n            \"values\": tuple([t.value for t in trials]),\n            \"range\": (min([t.value for t in trials]), max([t.value for t in trials])),\n        }\n    ]  # type: List[Dict[str, Any]]\n\n    for p_name in sorted_params:\n        values = []\n        for t in trials:\n            if p_name in t.params:\n                values.append(t.params[p_name])\n        is_categorical = False\n        try:\n            tuple(map(float, values))\n        except (TypeError, ValueError):\n            vocab = defaultdict(lambda: len(vocab))  # type: DefaultDict[str, int]\n            values = [vocab[v] for v in values]\n            is_categorical = True\n        dim = {\n            \"label\": p_name if len(p_name) < 20 else \"{}...\".format(p_name[:17]),\n            \"values\": tuple(values),\n            \"range\": (min(values), max(values)),\n        }  # type: Dict[str, object]\n        if is_categorical:\n            dim[\"tickvals\"] = list(range(len(vocab)))\n            dim[\"ticktext\"] = list(sorted(vocab.items(), key=lambda x: x[1]))\n        dims.append(dim)\n\n    traces = [\n        go.Parcoords(\n            dimensions=dims,\n            labelangle=30,\n            labelside=\"bottom\",\n            line={\n                \"color\": dims[0][\"values\"],\n                \"colorscale\": \"blues\",\n                \"colorbar\": {\"title\": \"Objective Value\"},\n                \"showscale\": True,\n                \"reversescale\": study.direction == StudyDirection.MINIMIZE,\n            },\n        )\n    ]\n\n    figure = go.Figure(data=traces, layout=layout)\n\n    return figure\n", "path": "optuna/visualization/parallel_coordinate.py"}]}