matplotlib.pyplotのimport時にSegmentation fault

# 環境

```
date 2018/10/18
Ubuntu 16.04
Anaconda 
conda 4.5.11
python 3.6.5
pip 18.0
```

# 現象

あるとき、pythonのスクリプトが急にSegmentation faultするようになりました。

特にスタックトレースも表示されず、原因特定は面倒でしたが、
どうもimport行で起こると気づいてからは、exit()を適当に差し込んで問題のあるモジュールを特定しました。

結果、

```
from matplotlib import pyplot as plt
```

が容疑行として浮上しました。

対話コンソールでも再現しました。

```
$ python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from matplotlib import pyplot
[1]    18382 segmentation fault (core dumped)  python
```

# 結論

```
conda install -c conda-forge opencv
```

でmatplotlib（というかpyplot）が使えなくなったとき、

## ソースコードの修正で対応する場合

https://github.com/matplotlib/matplotlib/issues/9294
を参考に、

```python:pythonのimport部分
import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
```

とりあえずこれで回避はできました。

## パッケージを入れなおす場合

ただ場合によってはソースコード編集ができない・やりたくないケースもあるだろうと思いますので、そのときは、

```
conda install qt
conda remove opencv
pip install opencv-python
```

と、Qtのバージョンを最新にしつつopencvをcondaからpipに変更します。

# 経緯

冒頭の現象が起こる直前、ChainerとcupyとOpenCVをインストールしていました。
どうも怪しそうなのはOpenCVです。OpenCVをインストールしたときの怪しそうなものをピックアップしました。

```
$ conda install -c conda-forge opencv
Solving environment: done

（中略）

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    cairo-1.14.12              |       he56eebe_3         1.3 MB  conda-forge

(中略)

    matplotlib-2.2.2           |           py36_1         9.2 MB  conda-forge
    ------------------------------------------------------------
                                           Total:       296.5 MB

The following NEW packages will be INSTALLED:

（中略）

The following packages will be UPDATED:

（中略）
    matplotlib:       2.2.2-py36h0e671d2_1                             --> 2.2.2-py36_1                         conda-forge
    numexpr:          2.6.5-py36h7bf3b9c_0                             --> 2.6.6-py36h470a237_1                 conda-forge
    numpy:            1.14.3-py36hcd700cb_1                            --> 1.15.2-py36_blas_openblashd3ea46f_1  conda-forge [blas_openblas]
    numpy-base:       1.14.3-py36h9be14a7_1                            --> 1.14.3-py36h0ea5e3f_1
    openssl:          1.0.2o-0                             conda-forge --> 1.0.2p-h470a237_1                    conda-forge
    scikit-learn:     0.19.1-py36h7aa7ec6_0                            --> 0.19.1-py36_blas_openblas_201        conda-forge [blas_openblas]
    scipy:            1.1.0-py36hfc37229_0                             --> 1.1.0-py36_blas_openblash7943236_201 conda-forge [blas_openblas]

The following packages will be DOWNGRADED:

（中略）
    pyqt:             5.9.2-py36h751905a_0                             --> 5.6.0-py36_2
    qt:               5.9.5-h7e424d6_0                                 --> 5.6.2-h974d657_12

```

Qtのバージョンを戻してみます。

```
$ conda install qt
Solving environment: done

（中略）

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    conda-4.5.11               |           py36_0         1.0 MB
    openssl-1.0.2p             |       h14c3975_0         3.5 MB
    libopencv-3.4.1            |       h1a3b859_1        41.5 MB
    opencv-3.4.1               |   py36h6fd60c2_2           7 KB
    certifi-2018.10.15         |           py36_0         139 KB
    py-opencv-3.4.1            |   py36h0676e08_1         1.2 MB
    ------------------------------------------------------------
                                           Total:        47.3 MB

The following NEW packages will be INSTALLED:

    libopencv:        3.4.1-h1a3b859_1
    py-opencv:        3.4.1-py36h0676e08_1

The following packages will be UPDATED:

    dbus:             1.13.0-h3a4f0e9_0                    conda-forge --> 1.13.2-h714fa37_1
    glib:             2.55.0-h464dc38_2                    conda-forge --> 2.56.1-h000015b_0
    gst-plugins-base: 1.12.5-hde13a9d_0                    conda-forge --> 1.14.0-hbbd80ab_1
    gstreamer:        1.12.5-h61a6719_0                    conda-forge --> 1.14.0-hb453b48_1
    matplotlib:       2.2.2-py36_1                         conda-forge --> 2.2.2-py36h0e671d2_1
    numpy-base:       1.14.3-py36h0ea5e3f_1                            --> 1.14.3-py36h9be14a7_1
    pyqt:             5.6.0-py36_2                                     --> 5.9.2-py36h751905a_0
    qt:               5.6.2-h974d657_12                                --> 5.9.5-h7e424d6_0

The following packages will be DOWNGRADED:

    blas:             1.1-openblas                         conda-forge --> 1.0-mkl
    ca-certificates:  2018.10.15-ha4d7672_0                conda-forge --> 2018.03.07-0
    cairo:            1.14.12-he56eebe_3                   conda-forge --> 1.14.12-h7636065_2
    certifi:          2018.10.15-py36_1000                 conda-forge --> 2018.10.15-py36_0
    conda:            4.5.11-py36_1000                     conda-forge --> 4.5.11-py36_0
    harfbuzz:         1.8.5-h2bb21d5_0                     conda-forge --> 1.7.6-h5f0a787_1
    numpy:            1.15.2-py36_blas_openblashd3ea46f_1  conda-forge [blas_openblas] --> 1.14.3-py36hcd700cb_1
    opencv:           3.4.3-py36_blas_openblash829a850_200 conda-forge [blas_openblas] --> 3.4.1-py36h6fd60c2_2
    openssl:          1.0.2p-h470a237_1                    conda-forge --> 1.0.2p-h14c3975_0
    scikit-learn:     0.19.1-py36_blas_openblas_201        conda-forge [blas_openblas] --> 0.19.1-py36h7aa7ec6_0
    scipy:            1.1.0-py36_blas_openblash7943236_201 conda-forge [blas_openblas] --> 1.1.0-py36hfc37229_0
```

すると、matplotlibはエラーがなくなりましたが、今度はOpenCVが死にます。

```
$ python using_opencv_script.py
Traceback (most recent call last):
  File "cupy_grid_automaton.py", line 7, in <module>
    import cv2
ImportError: /home/(censored)/anaconda3/lib/python3.6/site-packages/../../libopencv_dnn.so.3.4: undefined symbol: _ZNK6google8protobuf7Message25InitializationErrorStringB5cxx11Ev
```

https://github.com/ContinuumIO/anaconda-issues/issues/9601

の最初のアドバイス通り、モジュールを一部変更します。

```
% conda install -c defaults libprotobuf protobuf
Solving environment: done

（中略）

    protobuf:    3.5.2-py36_0     conda-forge --> 3.5.2-py36hf484d3e_1
    libprotobuf: 3.5.2-hd28b015_1 conda-forge --> 3.5.2-h6f1eeef_0
```

エラーが変わりました。

```
Traceback (most recent call last):
  File "cupy_grid_automaton.py", line 78, in <module>
    main()
  File "cupy_grid_automaton.py", line 67, in main
    cv2.imshow("test", img)
cv2.error: OpenCV(3.4.1) /opt/conda/conda-bld/opencv-suite_1527005194613/work/modules/highgui/src/window.cpp:636: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvShowImage
```

https://stackoverflow.com/questions/40207011/opencv-not-working-properly-with-python-on-linux-with-anaconda-getting-error-th

を見ていると、そもそもcondaのopencvは良くないのではと思い至り、

https://qiita.com/cointoss1973/items/92d82f9accb239a276a0

を参考に、

```
$ conda remove opencv
$ pip install opencv-python
```

としました。なお、一通りローカルで管理したいと思っているので、pipでもsudoはしませんでした。

これで改めてmatplotlibとOpenCVを両方試すと、ともに無事実行できました。

予想ですが、condaにおいて、OpenCVが対応するQtのバージョンと、matplotlibが対応するQtのバージョンが一致しないのが原因ではないかなと。

# その他

こういう試行錯誤を仮想環境とかでなく直にするからそのうちどうしようもなくなる。

ちなみに、OpenCVはcondaのものよりpyPI提供のものの方が結構実行速度が速いように感じました。