俺言語。

自分にしか理解できない言語で書かれた備忘録

【Python】グラフ枠(Spines)の色・太さ変更

グラフ枠(Spines)を一度描画した後に変更する方法。


グラフ枠は

ax.Spines{"Bottom"}
ax.Spines{"Top"}
ax.Spines{"Left"}
ax.Spines{"Right"}

に枠線のインスタンスがあり,

色変更は ax.Spines{"**"}.set_color(色)

太さ変更は ax.Spines{"**"}.set_linewidth(太さ)

で変更する。

問題は枠線(Spines)がAXESエリアのぎりぎり外側にいるため,

背景を保存する際や再描画エリアを指定する際に使う

ax.bboxでは範囲に含まれないこと。


解決方法として

ax.bbox.extended(縦?倍率,横?倍率)でax.bboxの範囲を少し広げてやる。

 問題点はAxesサイズが変わると拡張される面積も変わるためプログラム毎で調整が必要になってしまう。


ax.xaxis.get_tightbbox(ax.get_renderer_cache())でtickラベルを含むaxisのbboxを取得し,

 ax.bbox.union([結合したいbbox, 結合したいbbox])でbboxをつなげる。

 注意点はax.xaxis.get_tightbbox()がほんとにtightでtickラベルぎりぎりのbboxを返す。
 
 そのためtickラベルの桁数が変わる場合など簡単にエリアをはみ出すので注意。



グラフをダブルクリックしてグラフ枠を赤&太く -> 黒&細くを繰り返す。

def event_datacheck(self, event):
    if event.dblclick:

        if event.inaxes.spines["bottom"].get_edgecolor()[0] == 0:

            # 赤線を引く前にbgを保存
            # キーをイベントのaxesインスタンスにしてクリックされたaxesにbgを引き当て
            # key:axインスタンス value:bg
            self.ax_dict[event.inaxes] = event.canvas.copy_from_bbox(event.inaxes.bbox.expanded(1.1, 1.1))

            event.inaxes.spines["bottom"].set_color("red")
            event.inaxes.spines["top"].set_color("red")
            event.inaxes.spines["left"].set_color("red")
            event.inaxes.spines["right"].set_color("red")

            event.inaxes.spines["bottom"].set_linewidth(2)
            event.inaxes.spines["top"].set_linewidth(2)
            event.inaxes.spines["left"].set_linewidth(2)
            event.inaxes.spines["right"].set_linewidth(2)

            print("Axes was SELECTED")

        else:
            # イベント内のaxesに対応するbgを使って画面をbgに戻す
            event.canvas.restore_region(self.ax_dict[event.inaxes])

            event.inaxes.spines["bottom"].set_color("black")
            event.inaxes.spines["top"].set_color("black")
            event.inaxes.spines["left"].set_color("black")
            event.inaxes.spines["right"].set_color("black")

            event.inaxes.spines["bottom"].set_linewidth(0.5)
            event.inaxes.spines["top"].set_linewidth(0.5)
            event.inaxes.spines["left"].set_linewidth(0.5)
            event.inaxes.spines["right"].set_linewidth(0.5)

            print("Axes was RELEASED")

        event.inaxes.draw_artist(event.inaxes.spines["bottom"])
        event.inaxes.draw_artist(event.inaxes.spines["top"])
        event.inaxes.draw_artist(event.inaxes.spines["left"])
        event.inaxes.draw_artist(event.inaxes.spines["right"])

        # これで更新
        event.inaxes.figure.canvas.blit(event.inaxes.bbox.expanded(1.2, 1.2))
        # event.inaxes.figure.canvas.update() <- wxaggだと動かない