【Python】グラフに線・背景・文字などを追加する方法!

グラフ作成

概要|Pythonでグラフに線・背景・文字などを追加する方法の説明

こんにちは、すのくろです。

今回は、csvのような表データから作成されたグラフに対して、線や背景(範囲)、文字などを追加する方法について記載します。

以下のようなものが最終アウトプットの例です。

それでは解説していきます!

折れ線グラフ

必要なモジュールのインポート & csvデータの読み込み

はじめに、データの操作・計算やグラフ描画をしていくために、必要なモジュール(関数を使うためのパックみたいなもの)をインポートします。

続いて、扱いたいデータを読み込みます。

今回は、3個の指標(A, B, C)の平均値とそのばらつき(標準偏差)を6回の時間ごとにまとめた表を想定しています。

以下がその表データを成形したコードになります。

# 平均値
a = [3, 4, 5, 6, 3, 4]
b = [2, 3, 2, 4, 2, 1]
c = [3, 3, 4, 5, 7, 8]

# 標準偏差
aa = [0.4, 0.5, 0.6, 0.5, 0.5, 0.4]
bb = [0.3, 0.4, 0.5, 0.4, 0.3, 0.5]
cc = [0.7, 0.6, 0.5, 0.4, 0.6, 0.7]

# 時間
t = np.arange(1, 7)

df = pd.DataFrame({"Time": t, "A_mean": a, "B_mean": b, "C_mean": c, "A_sd": aa, "B_sd": bb, "C_sd": cc})
df
表データ

ここまでの内容は以前の折れ線グラフ作成の記事を参考にしてもらえると幸いです。

上記記事と同じようにまずは土台となる折れ線グラフを作成します。

コードは下記をコピペしてもらえればOKです。

x = df["Time"]
name = df.columns #凡例用に表の列名を取得
marker_list = ["o", "s", "^"] #マーカーの形のリスト(丸、四角、三角)を作成

plt.figure(figsize=(4, 3), dpi=200) 
for i in range(3): # 「1、2、3」という変数を順に渡す
    y = df.iloc[:, i+1] # 表dfの中で、全ての行の、i+1番目の列のデータを取得
    e = df.iloc[:, i+4] # 表dfの中で、全ての行の、i+4番目の列のデータを取得
    plt.errorbar(x, y, yerr=e, label=name[i+1], marker=marker_list[i], mec="k", capthick=1, capsize=2, lw=1) 
    plt.legend() #凡例を表示
    plt.xlabel('Time [min]')
    plt.ylabel('Value [-]')
    plt.xlim(0, 7)
    x = x+0.1 # 次の繰り返し時にx軸の値を右に少しずらす
通常の折れ線グラフ

これで、下準備となるグラフの作成が終わりました。

縦に垂直線を入れる vlines(x, ymin, ymax)

それでは、ここから本題の線を追加する方法について説明していきます。

初めに、垂直線を入れる方法です。

垂直線は、vlines(x, ymin, ymax) を使って入れます。

ちなみに「vlines」の「v」はvertical(垂直)の頭文字です。

各引数の意味は↓の通りです。

線の座標点(位置、始点、終点)を示しています。

  • x:線の位置(x座標)
  • ymin:線の下端の座標
  • ymax:線の上端の座標

それでは、実際に、vlinesを使ってみましょう。

x = df["Time"]
name = df.columns #凡例用に表の列名を取得
marker_list = ["o", "s", "^"] #マーカーの形のリスト(丸、四角、三角)を作成

plt.figure(figsize=(4, 3), dpi=200) 
for i in range(3): # 「1、2、3」という変数を順に渡す
    y = df.iloc[:, i+1] # 表dfの中で、全ての行の、i+1番目の列のデータを取得
    e = df.iloc[:, i+4] # 表dfの中で、全ての行の、i+4番目の列のデータを取得
    plt.errorbar(x, y, yerr=e, label=name[i+1], marker=marker_list[i], mec="k", capthick=1, capsize=2, lw=1) 
    plt.legend() #凡例を表示
    plt.xlabel('Time [min]')
    plt.ylabel('Value [-]')
    plt.xlim(0, 7)
    x = x+0.1 # 次の繰り返し時にx軸の値を右に少しずらす

 # 縦に垂直線を引く
xl = 3.5
ymin = 0
ymax = 9
plt.vlines(xl, ymin, ymax, color="k")

コードの前半部分は先ほどのグラフ作成のものと同じです。

このグラフ作成のコードに続けて、垂直線を入れるコードを後半部分に追加しました。

結果のグラフは↓の通りです。

垂直線入りグラフ

水平線 hlines(y, xmin, xmax)

続いて、水平線を入れる方法です。

水平線は、vlines(x, ymin, ymax) を使って入れます。

ちなみに「hlines」の「h」はhorizontal(水平な)の頭文字です。

各引数の意味はvlines()と考え方は同じで、線の座標点(位置、始点、終点)の↓の通りです。

  • y:線の位置(y座標)
  • xmin:線の左端の座標
  • xmax:線の右端の座標

それでは、実際に、hlinesを使ってみましょう。

↓のコードをグラフ作成後に付け加える形です。出力結果のグラフも合わせて表示します。

# 水平線を引く
yl = 6
xmin = 0.5
xmax = 6.5
plt.hlines(yl, xmin, xmax, color="k")
水平線入りグラフ

縦に範囲を描く axvspan(xmin, xmax)

ここからは、線ではなく一定の範囲を描く方法について説明していきます。

まずは縦に範囲を描くパターンです。

使う関数は、↓になります。

plt.axvspan(3, 4, color="gray", alpha=0.3)

今までと同様にこのコードをグラフ作成コードの後に続けて付け加えてもらえればOKです。

出力されるグラフは↓になります。

縦範囲指定グラフ

引数の1つ目はx軸の最小値(左端)、2つ目はx軸の最大値(右端)になります。

ここで範囲を灰色(gray)で塗りつぶし、引数alphaで透過率をつけてあげてます。

これによって、あまりマーカーなどの邪魔をせず、

グラフの指定範囲を色をつけて表現することができました!

今回は触れませんが、plt.axhlines()で横に範囲を指定したものも作れます。

考え方はplt.axvlines()もplt.axhlines()も同じなので、試してみてください。

文字を追加 text(x, y, “文字”)

最後に、グラフに文字を追加する方法について説明します。

グラフに文字を入れることができると、その範囲の条件や状態などがグラフからでもわかるようになり、理解しやすいグラフができるようになります!

文字を入れるために使う関数は

plt.text(x, y, text)

になります。

各引数の意味合いは下記の通りです。

  • x:文字が入る場所のx座標
  • y:文字が入る場所のy座標
  • text:入れたい文字(=文字列)

それでは、plt.text()を使って文字を入れてみましょう。

下記コード(垂直範囲+文字追加)を、グラフ作成コードの下に入れます。

# 縦に垂直範囲を描く
plt.axvspan(4.3, 4.9, color="gray", alpha=0.3)

# 文字入力
x = 4.3
y = 7
s = "AAA"
plt.text(x, y, s, color = "black")

出力結果↓

範囲指定+文字列追加グラフ

グラフ全体の色付けでデータの説明

最後にここまでの知識を使って、折れ線グラフを装飾して、値の時のタイミングや状況がどんな場合だったか等がわかるように変更してみたいと思います。

例えば、時間によって条件が「A → B → C」のように変化していく実験をグラフにも示してみたい時を考えます。

その場合は、範囲を色を変えて塗りつぶしたり、文字列A、B、C をその範囲内に入れることで表現できますね。

↓のコードで実現できます。

x = df["Time"]
name = df.columns #凡例用に表の列名を取得
marker_list = ["o", "s", "^"] #マーカーの形のリスト(丸、四角、三角)を作成

plt.figure(figsize=(4, 3), dpi=200) 
for i in range(3): # 「1、2、3」という変数を順に渡す
    y = df.iloc[:, i+1] # 表dfの中で、全ての行の、i+1番目の列のデータを取得
    e = df.iloc[:, i+4] # 表dfの中で、全ての行の、i+4番目の列のデータを取得
    plt.errorbar(x, y, yerr=e, label=name[i+1], marker=marker_list[i], mec="k", capthick=1, capsize=2, lw=1) 
    plt.legend() #凡例を表示
    plt.xlabel('Time [min]')
    plt.ylabel('Value [-]')
    plt.xlim(0, 7)
    x = x+0.1 # 次の繰り返し時にx軸の値を右に少しずらす

#範囲の最小値と最大値ののリスト
r_min = [0, 4.3, 4.9]
r_max = [4.3, 4.9, 7]
c_list = ["navy", "gray", "red"]
# for文で回す
for rr in range(3):
    plt.axvspan(r_min[rr], r_max[rr], color=c_list[rr], alpha=0.3)
    
#     文字入力
x = [3, 4.5, 5.5]
y = 7
s = ["A", "B", "C"]

for ss in range(3):
    plt.text(x[ss], y, s[ss], color="black")

出力結果↓

この図を見るだけで、条件の時間帯やその時の値の変化などが視覚的にわかりやすくなったのではないでしょうか。

これは一例に過ぎないので、似た考えを応用させながら色んな装飾グラフを作成してもらえれば幸いです。

ここまでお読みいただき、ありがとうございました!

コメント

タイトルとURLをコピーしました