matplotlibでグラフの色を連続的に変えてプロットし、legendを簡単にたくさん並べる方法

# matplotlib で色を変えて、legend をたくさん表示したい

## 使い所

matplotlib を使って、グラフをたくさん表示したいが、デフォルトの色の設定だと有限個の色しか出せない。これを簡単に解決する方法を紹介したい。そういう場合、legend もたくさん表示したいことが多いと思うが、昔の matplotlib では難しかったが、今はとても簡単にできるので、おまけでその方法も紹介する。

## サンプル

コードを見れば分かる方は、google colab で作成した例を参照ください。

https://colab.research.google.com/drive/1aeHwYAeXzc14ZxSW0NuSYZanGupqSWAW?usp=sharing

### 概要

例として、y = arctan((n+1)x) と y = x^n の２つの関数について、n を20個ずらしたグラフを重ね書きする例を紹介する。

### colormap のポイント

``` python
usercmap = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=num)
scalarMap = cm.ScalarMappable(norm=cNorm, cmap=usercmap)
````

これで、colormap で jet を選択し、0 から num(20) 個のデータ数で色分けを宣言して、cm.ScalarMappableで scalarMapを生成する。for loop の中で、
c = scalarMap.to_rgba(i) として、色を選択する。

### legendをたくさん表示するためのポイント

``` python:
plt.legend(bbox_to_anchor=(0., 1.01, 1., 0.01), loc='lower left',ncol=10, mode="expand", borderaxespad=0.,fontsize=8)
```

bbox_to_anchor=(X座標, Y座標, Xサイズ, Yサイズ)で置き場所を指定し、ncolで折りたたむコラム数を調節する。


### サンプルコード


``` qiita_legend_sample.py:

#!/usr/bin/env python 
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'serif'
import optparse
from matplotlib.colors import LogNorm
import matplotlib.colors as colors

### plot 1D plot : shifted 
F = plt.figure(figsize=(12,8.))
plt.subplots_adjust(wspace=0.3, hspace=0.6)

ax = plt.subplot(2,1,1)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)             
plt.figtext(0.02,0.02,"[matplotlib legend test]")
plt.xscale('linear')
plt.yscale('linear')
plt.grid(linestyle='dotted',alpha=0.5)
plt.xlabel(r'x-axis (a.u.)')
plt.ylabel(r'y-axis')        
x = np.arange(-1,1,0.1)
num=20
y = []
for j in range(num):
    y.append(np.arctan(x*(j+1)))

usercmap = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=num)
scalarMap = cm.ScalarMappable(norm=cNorm, cmap=usercmap)

for i,oney in enumerate(y):
    c = scalarMap.to_rgba(i)
    plt.errorbar(x, oney, fmt="o-", color = c, alpha = 0.8, linewidth = 1, label=str(i))        

plt.legend(bbox_to_anchor=(0., 1.01, 1., 0.01), loc='lower left',ncol=10, mode="expand", borderaxespad=0.,fontsize=8)


ax = plt.subplot(2,1,2)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)             
plt.xscale('linear')
plt.yscale('linear')
plt.grid(linestyle='dotted',alpha=0.5)
plt.xlabel(r'x-axis (a.u.)')
plt.ylabel(r'y-axis')        
x = np.arange(-1,1,0.1)
num=20
y = []
for j in range(num):
    y.append(np.power(x,j+1))

usercmap = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=num)
scalarMap = cm.ScalarMappable(norm=cNorm, cmap=usercmap)

for i,oney in enumerate(y):
    c = scalarMap.to_rgba(i)
    plt.errorbar(x, oney, fmt="o-", color = c, alpha = 0.8, linewidth = 1, label=str(i))        

plt.legend(bbox_to_anchor=(-0.1, 1.0, 1.2, 0.01), loc='lower left',ncol=10, mode="expand", borderaxespad=0.,fontsize=8)

plt.savefig("qiita_legend_sample.png")
plt.show()


```

生成される図はこちら。

![qiita_legend_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179652/29d053bc-bc13-f310-922a-d5be4b98a919.png)

### 注意事項

このように legend を横に広げてグラフの外に表示するのは簡単になったが、expandというオプションは横方向にのみ対応していて、縦には対応してない(2019.1.8現在)。時間が解決してくれると思うが。