PyQtGraphとmatplotlibを真面目に比較する2（散布図と見た目の変更）

[前回](https://qiita.com/Yukiho_P/items/66d15413f53941c1a569)の続きです．

# 環境
- Mac mini(M1) Big Sur
- Python 3.9.6(arm64)
- numpy 1.21.1
- matplotlib 3.4.3
- PyQtGraph 0.12.2

# 目標
　引き続きmatplotlibのグラフをPyQtGraphで描けるように頑張ります．散布図から線やマーカー，色の指定とかを調べたいですね．

# 実習
　前回同様にmatplotlibのコードをコメントに書いた後にPyQtGraphで対応するコードを記述していきます．またまた同様に以下を事前に読み込みます．

```head.py
import numpy as np
from matplotlib import pyplot as plt
import pyqtgraph as pg

np.random.seed(876)
x = np.linspace(0, 10, 100)
y = np.cos(x)
s = np.random.randn(100)/30
```

## Axes.scatter()
　matplotlibと異なり散布図専用の関数はなく，汎用の`plot`関数で線を消してマーカーを指定します．使いませんがmatplotlibでも同じことができますね．

```plot06.py
#fig, ax = plt.subplots()
#ax.scatter(x, y)
#ax.plot(x, y, linestyle='', marker='o')
win = pg.plot(x, y, pen=None, symbol='o')
```
![plot06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403698/21184321-de49-72f9-f109-847ce2eab43f.png)
　線の色の指定は`pen`で行います．matplotlibと同様に`r, g, b, c, m, y, k, w`が使える他，`(R, G, B, [A])`を**0から255の整数**で指定できるようです．matplotlibの`marker`に相当するのは`symbol`です．こちらはmatplotlibと異なるものも多いため[公式ドキュメント](https://pyqtgraph.readthedocs.io/en/latest/graphicsItems/scatterplotitem.html?highlight=triangle#pyqtgraph.ScatterPlotItem.setSymbol)で確認が必要です．線の色が`Pen`であったことから想像がつく通り，`symbol`の輪郭の色は`symbolPen`です．`markerfacecolor`に相当するのは`symbolBrush`，大きさは`symbolSize`です．[この他にも指定できるものがある](https://pyqtgraph.readthedocs.io/en/latest/graphicsItems/plotdataitem.html#pyqtgraph.PlotDataItem.__init__)ので必要に応じて確認して下さい．

### Line2D, PathCollection
　上でリンクを貼ってしまったので触れておきます．今まで細かいことは考えずに`fig = plt.figure()`の感覚で`win = pg.plot()`としてきました．こうして`Axes`に相当する`pg.PlotItem`のインスタンスが作られることは[前回にも紹介した公式の図](https://pyqtgraph.readthedocs.io/en/latest/plotting.html)
からも想像できると思います．公式ドキュメントを辿ると実際には`pg.plot() -> pg.PlotItem.plot() -> pg.PlotDataItem()`と呼び出されているようです．最後に現れた`PlotDataItem`がmatplotlibでいうところの`Line2D`と`PathCollection`を統括するクラスのようです．その子分にはちゃんと`PlotCurveItem`と`ScatterPlotItem`がいますが，ユーザー的には親分の`PlotDataItem`を操作すればいいように設計されているらしいです．すなわち`pen`や`symbol`などは巡り巡って`PlotDataItem`に渡されているということです．

## Axes.set_xlabel, Axes.set_title
　軸ラベルやグラフタイトルの指定方法です．

```plot07.py
#fig, ax = plt.subplots()
#ax.plot(x, y)
win = pg.plot(x, y, title='window title')

#ax.set(title='title', ylabel='left', xlabel='bottom')
win.setLabels(
        title='title',
        left='left', bottom='bottom',
        right='right', top='top'
    )
```
![スクリーンショット 2021-08-13 8.52.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403698/95073467-c285-6fa0-2c1e-a24b6a76688c.png)

　ウィンドウ内に複数のグラフがある場合は個別の`PlotItem`で指定します．

```plot08.py
#fig = plt.figure()
win = pg.GraphicsLayoutWidget(show=True)

#ax1 = fig.add_subplot(121).plot(x, y)
p1 = win.addPlot(x=x, y=y)

#ax2 = fig.add_subplot(122).plot(x, y)
#ax2.set(title='plot 2', xlabel='x')
p2 = win.addPlot(x=x, y=y, title='plot 2', bottom='x')

#ax1.set(title='plot 1', ylabel='y')
p1.setLabels(title='plot 1', left='y')
```
![スクリーンショット 2021-08-13 8.59.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403698/827841f0-66e9-9d74-0a6b-a87a46425a90.png)

## Axes.set_xticklabels()
　ドキュメント読んでも分かりませんでした．GUIウィンドウで平行移動や拡大縮小ができてしまうので，それを設定した`pg.AxisItem`を作成して`win.setAxisItems()`に渡すようですが・・・

## `sharey`
　軸の調整方法は分かっていませんが，軸の共有方法は分かりました．

```plot09.py
#fig = plt.figure()
win = pg.GraphicsLayoutWidget(show=True)

#ax1 = fig.add_subplot(121)
#ax1.plot(x, y)
p1 = win.addPlot(x=x, y=y)

#ax2 = fig.add_subplot(122, sharey=ax1)
#ax2.plot(x, y*10)
p2 = win.addPlot(x=x, y=y*10)
p2.setYLink(p1)
```
![plot09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403698/f94162a5-f46a-da3d-6f4e-31cd2dbf9c1e.png)
　画像はGUI上で縮尺調整と平行移動を行なった後ですが，左右のグラフで縦軸がちゃんと一致しています．

# 結論
　前回と合わせて最低限のグラフは描けるはず．

# 予定
1. [アニメーションの描画方法](https://qiita.com/Yukiho_P/items/68fb44192bf596460a50)と保存方法

ヒストグラムはbinの設定が手動になりそうなのとpandasから簡単に連携できなさそうだから諦め．

# 追記
　アニメーション描画まで完了．保存は苦戦するかも．