Google Colaboratoryでmatplotlibの練習（２回目）

https://qiita.com/toshikawa/items/1891c1b0fa4ceb10acb1

とは別のデータでいろいろ練習したので。

https://teratail.com/questions/346175

から

# データ
```python:DF
import pandas as pd
import matplotlib.pyplot as plt


d={"key": [s for s in 'ABCDEFG'], "val": [10,20,5,20,10,5,2]}
DF1 = pd.DataFrame(data=d,index=range(1,8))
DF2 = pd.DataFrame({"key":['B','E','F'],"val":[20,10,5]},index=[2,5,6])

DF=pd.concat([DF1,DF2]).sort_index().drop_duplicates()
DF
```

|index|key|val|
|--:|:-:|--:|
1|	A|	10
2|	B|	20
3|	C|	5
4|	D|	20
5|	E|	10
6|	F|	5
7|	G|	2

このデータから

>index 1,2,3で一つのグラフ　4,5,6で一つのグラフ　5,6,7で一つのグラフ

のリクエスト

# 作図

```python:plot
f, ax = plt.subplots(1, 3, figsize = (15, 5))

m, h = max(DF['val']), min(DF['val'])
for i in range(len(DF) // 3 + 1):
    end = len(DF) // 3
    if i < end:
        df = DF.iloc[i*3:i*3+3]
    else:
        df = DF.iloc[-3:]

    df.plot(y='val',ax=ax[i],title=''.join(df['key']),xticks=list(df.index),yticks=np.linspace(m, h, 3 ,dtype=int))
```

![plt1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/aca2dc8d-ffe1-69be-7953-9e8f45cc4e4d.png)

#解説

- `plt.subplots`で１行３列の面を設定。　`len(DF) // 3 +1`でもいいと思う。
- 動的に３行ずつ分割
- あまりだけ最後の３行が必要なので、`if`で条件判定
    - `iloc`で抽出する行を設定
- `df.plot`は`matplotlib.plot`のオプションと大体一緒
    - `ax=`に描画する面を指定するのは便利
    - `np.linspace`でy軸を指定
    - 後の_searborn_の画面を見るとなんかいい方法があると思う

とりあえずは綺麗にできた。

# _searborn_で作図
`col=`で分けると綺麗にできそうと思って作ってみた。

```python:searborn
mport pandas as pd
import matplotlib.pyplot as plt
import numpy as np


d={"key": [s for s in 'ABCDEFG'], "val": [10,20,5,20,10,5,2]}
DF1 = pd.DataFrame(data=d,index=range(1,8))
DF2 = pd.DataFrame({"key":['B','E','F'],"val":[20,10,5]},index=[2,5,6])

DF=pd.concat([DF1,DF2]).sort_index().drop_duplicates()

# 抽出行を配列で準備
l =[]
for i in range(len(DF) // 3 + 1):
    end = len(DF) // 3
    if i < end:
        l.append(list(DF.index[i*3:i*3+3]))
    else:
        l.append(list(DF.index[-3:]))

# l: [[1, 2, 3], [4, 5, 6], [5, 6, 7]]

# データフレームの準備
dfl=[]
for idx,lst in enumerate(l):
    dfl.append(DF.loc[lst,:])

df=pd.concat(dfl, ignore_index=True)
df['group']=df.index // 3

"""
df

	index	key	val	group
0	1	A	10	0
1	2	B	20	0
2	3	C	5	0
3	4	D	20	1
4	5	E	10	1
5	6	F	5	1
6	5	E	10	2
7	6	F	5	2
8	7	G	2	2
"""

# グループ分け
dfl = df.copy()
d = dict(dfl.groupby('group').apply(lambda x: ''.join(x.key)))

# d:  {0: 'ABC', 1: 'DEF', 2: 'EFG'}

dfl.group=dfl.apply(lambda x: d[x.group],axis=1)

# 作図
import seaborn as sns

g=sns.relplot(x='key',y='val',data=dfl,col='group',kind='line',facet_kws={'sharex':False})
g.set_titles(col_template="{col_name}")
```
![sns1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/f7d5b2a8-0163-cb57-f23a-430e18db68f8.png)

これまた綺麗にできた

# 解説
- データフレームをグループ分けできるようにとりあえず作り直し
    - 抽出行のリストを作成し、データフレームをそのリストで切り出し、リスト化
- `pd.concat`でデータフレーム作成
- `groupby`でグループ集計したところから辞書を作成して、表示列を作成
- 作画

#　手順を少なく

```python:df.plot
# 上のデータフレームの準備までは一緒

dfl=[]
for idx,lst in enumerate(l):
    dfl.append(DF.loc[lst,:])

df=pd.concat(dfl,ignore_index=True)

df.index=df.index // 3

g=df.groupby(level=0).plot(x='key')
```
![plot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/73560d01-c922-02d6-5878-4d96a22ba261.png)
![plot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/4a750c76-6ad5-1791-9e54-f63d16ac0f54.png)
![plot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/e7e182c0-837c-d5b8-83bc-5a7d7f78cf20.png)

一つ一つ`figure`を作成するのでレイアウトの準軟性はないけど、お手軽。

# 横にする

```python:上の作図から
grouped= df.groupby(level=0)

fig, axes = plt.subplots(1,3, figsize=(20,6), sharey=True)

for (ky, ax) in zip(grouped.groups.keys(), axes.flatten()):
    grouped.get_group(ky).plot(x='key',title=grouped.key.apply(''.join)[ky],ax=ax)

```
![plot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/f5d9c09e-beef-d556-61b7-897010533f97.png)

_searborn_じゃなくてもなんとかなった。

# まとめ

データフレームの加工が、やるたびに忘れていることが多くて時間がかかっているのでなんとかしたいです。