cufflinksでpearl02がValueErrorだと言われる件

# この記事の概要

* cuffkinksというpandasと相性抜群でめちゃくちゃ便利なプロットライブラリがあります。
    * https://github.com/santosjorge/cufflinks
* なんかエラーが出て全くプロットできない現象が発生したので、症状と対処法を書き残します。

結論としては`cufflinks`が依存している`plotly`のバージョンを2系に下げれば良いっぽいです。

この記事を書いてる途中で築いたけど、`cufflinks`の開発チームもすでにこの問題を把握してる模様なのでその内直ると思います。

https://github.com/santosjorge/cufflinks/issues/119

# 環境

* Ubuntu16.04
* python 3.5
* pipenv
* jupyter lab

# 症状

インストール

```shell
$ pipenv install cufflinks
```

まずimportした時点でwarningが出る。
何かがおかしい。

```python
import cufflinks
```

```:output
/home/sabaku20XX/.local/share/virtualenvs/hoge-1jnfWo2E/lib/python3.5/site-packages/plotly/graph_objs/_deprecations.py:558: DeprecationWarning:

plotly.graph_objs.YAxis is deprecated.
Please replace it with one of the following more specific types
  - plotly.graph_objs.layout.YAxis
  - plotly.graph_objs.layout.scene.YAxis


/home/sabaku20XX/.local/share/virtualenvs/hoge-1jnfWo2E/lib/python3.5/site-packages/plotly/graph_objs/_deprecations.py:531: DeprecationWarning:

plotly.graph_objs.XAxis is deprecated.
Please replace it with one of the following more specific types
  - plotly.graph_objs.layout.XAxis
  - plotly.graph_objs.layout.scene.XAxis
```

適当なDataFrameを作って`iplot()`を実行。

```python
import numpy
import pandas

cufflinks.go_offline()

df = pandas.DataFrame(numpy.random.rand(100, 10))
df.iplot()
```

以下のようにエラーになる。
非常に長いエラーだが、ポイントはこの部分だ思う。

`Invalid value of type 'builtins.str' received for the 'bgcolor' property of layout.legend Received value: 'pearl02'`

何か存在しないオプションを渡してしまったようだ。

```:output
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-0e77f6a1a45b> in <module>()
      3 df = pandas.DataFrame(numpy.random.rand(100, 10))
      4 
----> 5 df.iplot()
...
~/.local/share/virtualenvs/hoge-1jnfWo2E/lib/python3.5/site-packages/_plotly_utils/basevalidators.py in raise_invalid_val(self, v)
    214             typ=type_str(v),
    215             v=repr(v),
--> 216             valid_clr_desc=self.description()))
    217 
    218     def raise_invalid_elements(self, invalid_els):

ValueError: 
    Invalid value of type 'builtins.str' received for the 'bgcolor' property of layout.legend
        Received value: 'pearl02'

    The 'bgcolor' property is a color and may be specified as:
      - A hex string (e.g. '#ff0000')
      - An rgb/rgba string (e.g. 'rgb(255,0,0)')
      - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
      - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
      - A named CSS color:
            aliceblue, antiquewhite, aqua, aquamarine, azure,
            beige, bisque, black, blanchedalmond, blue,
            blueviolet, brown, burlywood, cadetblue,
            chartreuse, chocolate, coral, cornflowerblue,
            cornsilk, crimson, cyan, darkblue, darkcyan,
            darkgoldenrod, darkgray, darkgrey, darkgreen,
            darkkhaki, darkmagenta, darkolivegreen, darkorange,
            darkorchid, darkred, darksalmon, darkseagreen,
            darkslateblue, darkslategray, darkslategrey,
            darkturquoise, darkviolet, deeppink, deepskyblue,
            dimgray, dimgrey, dodgerblue, firebrick,
            floralwhite, forestgreen, fuchsia, gainsboro,
            ghostwhite, gold, goldenrod, gray, grey, green,
            greenyellow, honeydew, hotpink, indianred, indigo,
            ivory, khaki, lavender, lavenderblush, lawngreen,
            lemonchiffon, lightblue, lightcoral, lightcyan,
            lightgoldenrodyellow, lightgray, lightgrey,
            lightgreen, lightpink, lightsalmon, lightseagreen,
            lightskyblue, lightslategray, lightslategrey,
            lightsteelblue, lightyellow, lime, limegreen,
            linen, magenta, maroon, mediumaquamarine,
            mediumblue, mediumorchid, mediumpurple,
            mediumseagreen, mediumslateblue, mediumspringgreen,
            mediumturquoise, mediumvioletred, midnightblue,
            mintcream, mistyrose, moccasin, navajowhite, navy,
            oldlace, olive, olivedrab, orange, orangered,
            orchid, palegoldenrod, palegreen, paleturquoise,
            palevioletred, papayawhip, peachpuff, peru, pink,
            plum, powderblue, purple, red, rosybrown,
            royalblue, saddlebrown, salmon, sandybrown,
            seagreen, seashell, sienna, silver, skyblue,
            slateblue, slategray, slategrey, snow, springgreen,
            steelblue, tan, teal, thistle, tomato, turquoise,
            violet, wheat, white, whitesmoke, yellow,
            yellowgreen
```

# 調査

なんか`plotly`がメジャーバージョンアップしたてなのが気になる。

```shell
$ pip freeze | grep cufflinks
cufflinks==0.13.0
$ pip freeze | grep plotly
plotly==3.0.0
```

情報源がどこかに行ってしまったけど、plotly 3.0で廃止された物を呼びだそうとしちゃってるっぽい。

cufflinksのsetup.pyにはplotlyのバージョン指定が特に入ってないので、cufflinksの想定より新しいバージョンのplotlyが入っちゃってるんですかねー。

https://github.com/santosjorge/cufflinks/blob/1553c59fc257e969954783f25fc1ad8f192ff2d0/setup.py

# 対処

plotlyのリリース履歴を見てみる。plotly 2系で一番新しいやつだと、`plotly 2.7.0`ですかね。

https://pypi.org/project/plotly/#history

3.0.0を消したうえで2.7.0を入れなおす。

```shell
$ pipenv uninstall plotly  # 3.0.0を消す
$ pipenv install plotly==2.7.0  # バージョン指定して入れなおす
```

もう一度やってみる。

```python
import numpy
import pandas
import cufflinks

cufflinks.go_offline()

df = pandas.DataFrame(numpy.random.rand(100, 10))
df.iplot(subplots=True)
```

できた。

![newplot.png](https://qiita-image-store.s3.amazonaws.com/0/240919/374eb494-47da-af86-b481-4adbbfaa5e46.png)