seabornでMatplotlibDeprecationWarningが出る場合の対処法

### 追記 (2019年4月29日)

以前出した [本件の修正プルリクエスト](https://github.com/mwaskom/seaborn/pull/1643) がマージされたので、最新版ではもうこの警告は出ないと思います。

---

Python で [Matplotlib](https://matplotlib.org/) を使う時に [seaborn](https://seaborn.pydata.org/) を使うと綺麗なグラフが描画できるのでよく使っています。

しかし、 seaborn を使っている時に以下のような警告が出るようになりました。

```bash
/Users/xxxx/.local/share/virtualenvs/xxxx/lib/python3.7/site-packages/matplotlib/__init__.py:855: MatplotlibDeprecationWarning:
examples.directory is deprecated; in the future, examples will be found relative to the 'datapath' directory.
  "found relative to the 'datapath' directory.".format(key))
/Users/xxxx/.local/share/virtualenvs/xxxx/lib/python3.7/site-packages/matplotlib/__init__.py:846: MatplotlibDeprecationWarning:
The text.latex.unicode rcparam was deprecated in Matplotlib 2.2 and will be removed in 3.1.
  "2.2", name=key, obj_type="rcparam", addendum=addendum)
```

環境は以下の通り。

```python
>>> import seaborn as sns
>>> sns.__version__
'0.9.0'
>>> sns.mpl.__version__
'3.0.2'
```

## TL;DR

- `seaborn.reset_orig()` を呼び出すと上記の警告が出る。
- matplotlibrc 等で RC パラメータを設定していない場合は、 `seaborn.reset_orig()` の代わりに `seaborn.reset_defaults()` を使えばいい。
- matplotlibrc 等で RC パラメータを設定している場合は、 `warnings.filterwarnings` で警告を消すしかない。

```python
import warnings
warnings.filterwarnings('ignore', category=matplotlib.MatplotlibDeprecationWarning)
```

結論としては本当に身も蓋もない感じだが、調べても情報がなかったので記録として残しておく。

**追記 (2019年1月4日)**
コメントで @skotaro さんに、警告が出ている原因となる RC パラメータを直接除くことでも解決できることを教えていただきました :pray: 

```python
import seaborn as sns
del sns._orig_rc_params['examples.directory']
del sns._orig_rc_params['text.latex.unicode']
```

## 原因

色々試したところ `seaborn.reset_orig()` が警告の原因だった。
[ソースコード (https://github.com/mwaskom/seaborn)](https://github.com/mwaskom/seaborn) を見ると、以下のようになっている。

```python:seaborn/rcmod.py
from . import palettes, _orig_rc_params


def reset_defaults():
    """Restore all RC params to default settings."""
    mpl.rcParams.update(mpl.rcParamsDefault)


def reset_orig():
    """Restore all RC params to original settings (respects custom rc)."""
    mpl.rcParams.update(_orig_rc_params)
```

```python:seaborn/__init__.py
# Capture the original matplotlib rcParams
import matplotlib as mpl
_orig_rc_params = mpl.rcParams.copy()
```

この `_orig_rc_params` はただの辞書であり、その中に `examples.directory` や `text.latex.unicode` といった Deprecated な RC パラメータが含まれているのが警告の原因である。

- https://matplotlib.org/api/api_changes.html#rcparams

なお `reset_defaults()` と `reset_orig()` という二つの関数が用意されているのには理由がある。

- `reset_defaults()` : Matplotlib のデフォルトのパラメータに戻す。
- `reset_orig()` : seaborn が読み込まれる直前のパラメータに戻す。

`reset_orig()` は、 matplotlibrc 等で seaborn が読み込まれる前に RC パラメータが変更された場合でも、 seaborn が読み込まれる前の状態に戻すことができる。

ちなみに、 `mpl.rcParams.copy()` と `mpl.rcParamsDefault` では以下のように型が異なる。

```bash
>>> import matplotlib as mpl
>>> type(mpl.rcParamsDefault)
<class 'matplotlib.RcParams'>
>>> type(mpl.rcParams.copy())
<class 'dict'>
```

## 追記 (2019年1月10日)

この件について seaborn に Issue を立てて [修正のプルリクエスト](https://github.com/mwaskom/seaborn/pull/1643) を送ったところ、seaborn の作者から以下のような返信が来ました。

> Thanks. I agree that this warning is annoying. But it's ultimately harmless, and reset_orig should be a rarely called function. I would worry that catching all deprecation warnings would cause us to miss cases where matplotlib deprecates parameters that are relevant to seaborn. Ultimately the costs of doing so outweigh the benefits of reducing a bit of noise, in my view.

ざっくり訳すとこんな感じ。

> ありがとう。この警告がうるさいことには同意します。しかし、これは結局のところ無害であり、そもそも reset_orig は滅多に呼ばれない関数であるべきです。私はすべての非推奨の警告を無視した場合に、matplotlib が seaborn に関連するパラメータを非推奨にしたときに見逃すかもしれないことを心配しています。結局、そうするコストとノイズを少し減らすメリットを考えた時に、コストの方が上回るというのが私の考えです。

ということなので、警告は我慢しましょう。