SPSS Modelerの棒グラフノードをPythonで書き換える

SPSS Modelerの棒グラフノードをPythonのmatplotlibやpandasのplotで書き換えてみます。

#0．データ
サンプルで利用するデータは以下です。
M_CD: マシンコード
UP_TIIME: 起動時間
POWER: 電力
TEMP: 温度
PRESSURE：圧力フラグ
ERR_CD: エラーコード

各マシンコードごとに起動時間にそって電力や温度の変化、圧力スイッチ、そしてエラーがあればそれが時系列に記録されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1e739d26-7c0f-3f6d-7c91-9934e64ba6c3.png)



#1m．棒グラフ。Modeler版

まず、データ型ノードの尺度でPRESSUREをフラグ型、ERR_CDを名義型に設定します。Modelerはデータの尺度によって使える設定項目が変わり、間違った設定を防止しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/eac55219-beef-616f-5c3c-b983066e4de0.png)

一つ目のグラフとして、各ERR_CDの件数で棒グラフを作成します。
フィールドにERR_CDを選択して実行します。事前に集計をしなくていいので簡単です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/68505c1f-8173-a6be-5cfd-520032920922.png)
結果は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/74460acb-aaaf-1d42-0431-9860461f8d3d.png)

2つ目のグラフとして積み上げ棒グラフを作成します。
フィールドにERR_CDを選択することに加えて、実行します。オーバーレイの色でPRESSUREを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6d204c16-7034-9920-853a-c6b9fb428730.png)

結果は以下です。ERR_CDの件数が棒グラフで出ることは同じなのですが、各ERR_CDでのPRESSUREのフラグの件数で色分けされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/26210f8f-88e6-ad0f-bdcb-a0de742fb499.png)

3つ目のグラフとして100%積み上げ棒グラフを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cf453e82-9eae-371b-77bf-b31de56c5620.png)

件数ではなく、各ERR_CDでのPRESSUREの件数の割合が表現されましたERR_CD=0や202でのPRESSURE１の割合が高いことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/213b911d-dd1b-444d-10c8-2edbfa46e8c2.png)


#1p．棒グラフ。matplotlib,pandas版
matplotlibやpandasのplot()メソッドをつかって棒グラフを作成します。


まず、PRESSUREとERR_CDについてはデータ型をカテゴリ型に設定します。

```python
df['PRESSURE'] = df['PRESSURE'].astype('category')
df['ERR_CD'] = df['ERR_CD'].astype('category')
print(df.dtypes)
```
M_CD           int64
UP_TIME        int64
POWER          int64
TEMP           int64
PRESSURE    category
ERR_CD      category
dtype: object

これでカテゴリ値が認識され、以下のようにアクセス可能になります。

```python
df['ERR_CD'].cat.categories
```
Int64Index([0, 101, 202, 303], dtype='int64')


一つ目のグラフとして、各ERR_CDの件数で棒グラフを作成します。
以下のようにまずERR_CDごとの件数をdf.groupby('ERR_CD').size()で集計します。

```python
dfErrcdGrp=df.groupby('ERR_CD').size()
dfErrcdGrp
```
ERR_CD
0      4589
101     531
202     549
303     133
dtype: int64

plt.barのxにindex,yにvalueを設定し、棒グラフを表示します。

```python
plt.bar(dfErrcdGrp.index.astype('str'), dfErrcdGrp)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4a889508-6c12-65e8-48bb-ed870c435261.png)

なお、indexはastype('str')で文字列型に変換しないと、カテゴリ値ではなく連続値扱いになるため、読みにくいグラフになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/20ae8822-6e16-cabd-725c-79cc6af15fb3.png)

* 参考:matplotlib で棒グラフを描く – Python でデータサイエンス

https://pythondatascience.plavox.info/matplotlib/%E6%A3%92%E3%82%B0%E3%83%A9%E3%83%95

同じグラフをpandasのplotメソッドをつかって書いてみます。pandasのplotメソッドはmatplotlibのラッパー関数ですが、pandasのDataframeやSeriesからmatplotlibよりも簡単にグラフを書くことができます。

以下だけで棒グラフを書くことができます。Seriesデータのindexをx、valueをｙに自動的にセットしています。

```python
dfErrcdGrp.plot.bar()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/06fe9a3a-f769-4fec-7e7b-1a9a13e1649d.png)

- 参考：pandasのplotメソッドでグラフを作成しデータを可視化

https://note.nkmk.me/python-pandas-plot/

2つ目のグラフとして積み上げ棒グラフを作成します。これはmatplotlibで書くと大変なので、pandasのplotメソッドで書きます。
まず、crosstabでERR_CDとPRESSUREでクロス集計表を作ります。ModelerのようにPRESSURE=1から積み上げたいので、reindexで1,0の順序になるように入れ替えています。通常は0よりも1に注目したいことが多いので、Modelerと同様に1から積み上げたほうが見やすいグラフになります。

```python
dfcross=pd.crosstab(df['ERR_CD'],df['PRESSURE'])
dfcross=dfcross.reindex(['1','0'],axis="columns")
dfcross
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/dbb45547-29fe-e64f-a562-caa73adf245b.png)


- 参考：Python - pandasクロス集計で行と列の位置を調整するにはどうすればよいですか？ 

https://qapicks.com/question/64739781-7f15488efe08

後は積み上げを有効にするstacked=Trueをオプションで指定して表示します。

```python
dfcross.plot.bar(stacked=True)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e4190969-bdb4-87f5-6d60-f332e286a153.png)


3つ目のグラフとして100%積み上げ棒グラフを作成します。

crosstabでnormalize='index'のオプションをつけてクロス集計表を作ります。

```python
dfcross=pd.crosstab(df['ERR_CD'],df['PRESSURE'], normalize='index')
dfcross=dfcross.reindex(['1','0'],axis="columns")
dfcross
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8ee529be-a862-9bdf-4d91-ee4e7aaaa003.png)


後はやはりstacked=Trueをオプションで指定して表示します。

```python
dfcross.plot.bar(stacked=True)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cae887ef-987c-7b9f-5ce8-e854d4b0fcde.png)

- 参考：Pythonで簡単！2行で描ける100％積み上げ棒グラフ（帯グラフ） - おうちだいすき
- 
https://loveshome.hatenablog.jp/entry/2018/12/05/232902


#2. サンプル
サンプルは以下に置きました。

ストリーム
https://github.com/hkwd/200611Modeler2Python/blob/mastergraph/graph.str?raw=true
notebook
https://github.com/hkwd/200611Modeler2Python/blob/master/graph/graph.ipynb
データ
https://raw.githubusercontent.com/hkwd/200611Modeler2Python/master/data/Cond5n_e.csv

■テスト環境
Modeler 18.3
Windows 10 64bit
Python 3.8.5
pandas 1.0.5

#3. 参考情報

棒グラフの「作図」タブ - IBM Documentation

https://www.ibm.com/docs/ja/spss-modeler/18.3.0?topic=node-distribution-plot-tab