= gwpy.plot (プロット機能の構造と詳細) = <> == 概要: Matplotlib との関係 == GWpyのプロット機能は、Pythonの標準グラフ描画ライブラリ '''Matplotlib''' を継承・拡張したものです。 基本的には「Matplotlibの機能はすべて使える」上に、「重力波データ特有の面倒な処理」を自動化してくれます。 * '''gwpy.plot.Plot''' <- '''matplotlib.figure.Figure''' (を継承) * '''gwpy.plot.Axes''' <- '''matplotlib.axes.Axes''' (を継承) == GWpy特有の軸・ラベル処理 == Matplotlibと最も挙動が異なるのが、「軸」と「ラベル」の自動処理です。 === 1. 時間軸 (GPS vs Relative) === {{{TimeSeries}}} をプロットすると、GWpyは自動的に横軸を「GPS時刻」または「ある時刻からの相対時間」に切り替えます。 * '''auto_gps=True''' (デフォルト): * 表示範囲が短い場合 -> 開始時刻 ({{{epoch}}}) を0とした '''相対時間 (秒)''' で表示。 * 表示範囲が長い場合 -> '''GPS時刻''' または '''日付 (UTC)''' で表示。 * '''epoch''': * 相対時間表示にする際の「基準時刻 (0秒とする点)」を指定します。指定しない場合はデータの {{{t0}}} が使われます。 {{{ # イベント時刻(1187008882.4) を0秒として表示する例 plot = data.plot(epoch=1187008882.4) }}} === 2. 単位の自動整形 === データ ({{{TimeSeries}}} 等) が {{{astropy.units}}} の単位情報を持っている場合、軸ラベルに自動的に単位が表示されます。 * 例: {{{unit='m'}}} -> 軸ラベル: {{{Amplitude [m]}}} * 例: {{{unit='1/sqrt(Hz)'}}} -> 軸ラベル: {{{Amplitude [1/sqrt(Hz)]}}} (ルート記号などで綺麗に表示されます) これを無効化して手動でラベルを設定したい場合は、通常の {{{ax.set_xlabel()}}} 等で上書き可能です。 == GWpy特有の色 (GWpy Colors) == GWpyは、検出器ごとの標準カラーを **名前付きカラー** として定義しています。 これらは自動的に適用されるわけではありませんが、`color` 引数に指定することで、公式プロットなどで使われる標準的な色使いを再現できます。 === 定義されているカラー名 === || '''名前 (Key)''' || '''色味''' || '''説明''' || || {{{'gwpy:ligo-hanford'}}} || 赤 (Red) || H1 の標準色 || || {{{'gwpy:ligo-livingston'}}} || 青 (Blue) || L1 の標準色 || || {{{'gwpy:virgo'}}} || 紫 (Purple) || V1 の標準色 || || {{{'gwpy:kagra'}}} || オレンジ (Orange) || K1 の標準色 || === 使用例 === {{{ # KAGRAのデータを標準色(オレンジ)でプロット plot = data.plot(color='gwpy:kagra', label='KAGRA') # 複数の検出器を標準色で比較 ax = plot.gca() ax.plot(h1_data, color='gwpy:ligo-hanford', label='H1') ax.plot(l1_data, color='gwpy:ligo-livingston', label='L1') ax.legend() }}} ※ 指定しない場合は、Matplotlibのデフォルトのカラーサイクル(青 -> オレンジ -> 緑...)が順に使われます。 == ログ/リニアの切り替え == {{{.plot()}}} した直後の軸スケールは、データの種類にかかわらず **Linear (線形)** であることが多いため、スペクトルなどの場合は手動で対数軸に設定する必要があります。 {{{ # ASDを片対数(X=log, Y=log)で描きたい場合 # plot() の引数で指定するのが一番簡単です plot = asd.plot(xscale='log', yscale='log') }}} == 応用的なプロット機能 == === plot_mmm (Min/Max/Mean) === 長時間(数時間〜数日)のトレンドデータ(平均値、最大値、最小値を持つデータ)を描画するためのメソッドです。 これはデータクラスのメソッドではなく、**Axes (軸) のメソッド**として実装されています。 {{{ from gwpy.plot import Plot # min, mean, max の3つの TimeSeries を用意したと仮定 plot = Plot() ax = plot.gca() # plot_mmm(mean, min, max) の順で渡す ax.plot_mmm(mean_data, min_data, max_data, color='gwpy:kagra') plot.show() }}} * 薄い塗りつぶし: Min〜Max の範囲 * 濃い線: Mean (平均値) === BodePlot (ボード線図) === 伝達関数 ({{{FrequencySeries}}} (複素数)) をプロットすると、自動的に {{{BodePlot}}} クラスが使われ、**ゲインと位相の2つのサブプロット** が生成されます。 通常の {{{plot.gca()}}} では片方の軸しか取れないため、専用の属性 {{{maxes}}} (Magnitude Axes) と {{{paxes}}} (Phase Axes) を使ってアクセスします。 {{{ tf = data.transfer_function(...) plot = tf.plot() # BodePlotオブジェクト # 軸の取得 ax_mag = plot.maxes ax_phase = plot.paxes ax_mag.set_title('Transfer Function') ax_phase.set_ylabel('Phase [deg]') plot.show() }}} === Spectrogram (スペクトログラム) === スペクトログラムのプロットでは、色の濃淡(Z軸)の調整が重要です。 Matplotlibの {{{imshow}}} や {{{pcolormesh}}} の引数がそのまま使えます。 {{{ # norm=LogNorm() を使うためにインポート from matplotlib.colors import LogNorm spec = data.spectrogram(...) # 対数カラー、範囲指定 (vmin, vmax) plot = spec.plot(norm=LogNorm(), vmin=1e-23, vmax=1e-19) # カラーバーの追加 ax = plot.gca() plot.colorbar(label='Amplitude') plot.show() }}} === StateVector / Segment (状態フラグ) === データの品質フラグ(ロック状態かどうか等)を表示するための専用メソッドです。 * '''SegmentList.plot()''': 「データが存在する区間」をバーで表示。 * '''StateVector.plot()''': ビットごとのON/OFFを時系列で表示。 {{{ from gwpy.segments import SegmentList segs = SegmentList(...) plot = segs.plot() # 横軸: 時刻, 縦軸: フラグの有無 }}} == 複雑なレイアウトと個別設定 == === 重ね書きと Subplot の混合 === {{{gwpy.plot.Plot}}} コンストラクタを使うと、柔軟なレイアウトが可能です。 {{{ from gwpy.plot import Plot # 上段に2つのデータを重ね書き、下段に別のデータを描画 # geometry=(行, 列) plot = Plot(geometry=(2, 1)) # 上段 (ax1) に追加 ax1 = plot.get_axes()[0] ax1.plot(data1, label='Data 1', color='red') ax1.plot(data2, label='Data 2', color='blue') ax1.legend() # 下段 (ax2) に追加 ax2 = plot.get_axes()[1] ax2.plot(data3, color='green') plot.show() }}} === Plot(...) でまとめて描画する際の個別設定 === {{{Plot(data1, data2, ...)}}} のようにまとめて渡す際、色指定などでリストを渡す方法は挙動が不安定な場合があるため、以下のように {{{separate=True}}} を使うか、1つずつ追加する方法を推奨します。 {{{ # data1 は赤、data2 は青で描きたい場合 plot = Plot() ax = plot.gca() # 1つずつ追加するのが一番確実 ax.plot(data1, color='red', label='Main') ax.plot(data2, color='blue', label='Reference') ax.legend() plot.show() }}}