質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.03%

matplotlibを使用したグラフ表示で条件による背景色変更を行いたい。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 256

前提・実現したいこと

pythonのmatplotlibを使用してグラフ表示アプリを作成しています。
0~50までのランダムな数値が入っているデータフレームがあり、それを折れ線グラフで表示する。
グラフ上で、通常背景色は白で、25以下の値の背景色は黄色に、
25以下が5個以上続く場合には背景色をオレンジにするという条件があります。

発生している問題・エラーメッセージ

1)下記に記述する現在の方法でも背景色が変わっているように見えるのですが、強引すぎるやり方で効率悪いかと思います。
別の単純なやり方があれば教えてください。

2)現在の手順だとグリッドが最背面にあり、黄色、オレンジの部分はメモリ線が見えなくなる状況です。
vlinesを最背面にする方法、もしくはgridを最前面にする方法があれば教えてください。

該当のソースコード

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np 

def main():
  df = pd.DataFrame(np.random.randint(0,50,size=(1000,1)),columns=list('A'))

  df2 = df[df['A']<=25]
  df2 = df2.reset_index()
  df2['diff'] = df2['index'].diff()

  cnt = 0
  df2['オレンジ'] = 0
  for i in range(len(df)):
    if df2['diff'].get(i,None) == 1.0:
      cnt += 1
      if cnt >= 5:
        df2.loc[i-5:i,'オレンジ'] = df2.loc[i-5:i,'index']
    else:
      cnt = 0

  fig = plt.figure()
  plt.grid(b=None, which='both', axis='both')
  plt.plot(df['A'],color='blue')
  plt.vlines(df2['index'],0,50,color='yellow')
  plt.vlines(df2['オレンジ'],0,50,color='orange')

  plt.show()
if __name__ == '__main__':
  main()

試したこと

グラフ表示部は、背景色が変わった風に見せるために縦線を描いている状況です。

補足情報(FW/ツールのバージョンなど)

Python 3.7.3
matplotlib : 3.0.3

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

下記に記述する現在の方法でも背景色が変わっているように見えるのですが、強引すぎるやり方で効率悪いかと思います。

値1つごとに背景を決める必要があるので、特に問題があるように思えません。
vlines でよいと思います。

現在の手順だとグリッドが最背面にあり、黄色、オレンジの部分はメモリ線が見えなくなる状況です。
vlinesを最背面にする方法、もしくはgridを最前面にする方法があれば教えてください。

set_axisbelow(False) を設定することで、目盛り、グリッドを前面に表示できます。

matplotlib.axes.Axes.set_axisbelow — Matplotlib 3.1.0 documentation

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np


def main():
    df = pd.DataFrame(np.random.randint(0, 50, size=(1000, 1)), columns=["A"])

    df2 = df[df["A"] <= 25]
    df2 = df2.reset_index()
    df2["diff"] = df2["index"].diff()

    cnt = 0
    df2["オレンジ"] = 0
    for i in range(len(df)):
        if df2["diff"].get(i, None) == 1.0:
            cnt += 1
            if cnt >= 5:
                df2.loc[i - 5 : i, "オレンジ"] = df2.loc[i - 5 : i, "index"]
        else:
            cnt = 0

    fig = plt.figure(figsize=(10, 5))
    plt.gca().set_axisbelow(False)
    plt.grid(b=None, which="both", axis="both", color="k")
    plt.plot(df["A"], color="blue", lw=0.5)

    plt.vlines(df2["index"], 0, 50, color="yellow")
    plt.vlines(df2["オレンジ"], 0, 50, color="orange")

    plt.show()


if __name__ == "__main__":
    main()

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

  • 25以下の開始~終了のx位置=yellowの範囲
  • 25以下が5個以上続く開始~終了のx位置=orangeの範囲

をコードでうまく特定する処理が書ければ、あとはaxvspanで指定範囲を塗りつぶせます。
参考:Different background colour areas on matplotlib plot

以下は単純な例です。

import matplotlib.pyplot as plt

# サンプルデータ
y = [28,24,30,24,23,22,21,20,19,29,30]
x = list(range(len(y)))

fig, ax = plt.subplots()
ax.plot(x, y, 'k')
ax.grid()

# 範囲は手作業で適当にセット
ax.axvspan(0.5, 1.5, facecolor='yellow', alpha=0.5)
ax.axvspan(2.5, 8.5, facecolor='orange', alpha=0.5)

plt.show()


イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる