前回の続きです.
環境
- 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で対応するコードを記述していきます.またまた同様に以下を事前に読み込みます.
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でも同じことができますね.
# fig, ax = plt.subplots()
# ax.scatter(x, y)
# ax.plot(x, y, linestyle='', marker='o')
win = pg.plot(x, y, pen=None, symbol='o')

線の色の指定はpenで行います.matplotlibと同様にr, g, b, c, m, y, k, wが使える他,(R, G, B, [A])を0から255の整数で指定できるようです.matplotlibのmarkerに相当するのはsymbolです.こちらはmatplotlibと異なるものも多いため公式ドキュメントで確認が必要です.線の色がPenであったことから想像がつく通り,symbolの輪郭の色はsymbolPenです.markerfacecolorに相当するのはsymbolBrush,大きさはsymbolSizeです.この他にも指定できるものがあるので必要に応じて確認して下さい.
Line2D, PathCollection
上でリンクを貼ってしまったので触れておきます.今まで細かいことは考えずにfig = plt.figure()の感覚でwin = pg.plot()としてきました.こうしてAxesに相当するpg.PlotItemのインスタンスが作られることは前回にも紹介した公式の図
からも想像できると思います.公式ドキュメントを辿ると実際にはpg.plot() -> pg.PlotItem.plot() -> pg.PlotDataItem()と呼び出されているようです.最後に現れたPlotDataItemがmatplotlibでいうところのLine2DとPathCollectionを統括するクラスのようです.その子分にはちゃんとPlotCurveItemとScatterPlotItemがいますが,ユーザー的には親分のPlotDataItemを操作すればいいように設計されているらしいです.すなわちpenやsymbolなどは巡り巡ってPlotDataItemに渡されているということです.
Axes.set_xlabel, Axes.set_title
軸ラベルやグラフタイトルの指定方法です.
# 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'
)
ウィンドウ内に複数のグラフがある場合は個別のPlotItemで指定します.
# 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')
Axes.set_xticklabels()
ドキュメント読んでも分かりませんでした.GUIウィンドウで平行移動や拡大縮小ができてしまうので,それを設定したpg.AxisItemを作成してwin.setAxisItems()に渡すようですが・・・
sharey
軸の調整方法は分かっていませんが,軸の共有方法は分かりました.
# 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)

画像はGUI上で縮尺調整と平行移動を行なった後ですが,左右のグラフで縦軸がちゃんと一致しています.
結論
前回と合わせて最低限のグラフは描けるはず.
予定
- アニメーションの描画方法と保存方法
ヒストグラムはbinの設定が手動になりそうなのとpandasから簡単に連携できなさそうだから諦め.
追記
アニメーション描画まで完了.保存は苦戦するかも.

