今回の記事では、グラフの軸ラベルを斜めにする方法を扱います。
いくつか方法はありますが、その中から個人的に納得しやすく、応用にも使いやすいと感じた方法を紹介します。
コードと結果例
細かな説明の前に、描画部分と結果を紹介します。
まず、前提として、下記のコードを実行しています。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import datetime
準備したデータフレームはこのような感じです。5分ごとのデータを1000行用意しました。
c_df.head()
datetime | C1 | |
---|---|---|
0 | 2018-03-01 00:00:00 | 0.000000 |
1 | 2018-03-01 00:10:00 | 1.764052 |
2 | 2018-03-01 00:20:00 | 2.164210 |
3 | 2018-03-01 00:30:00 | 3.142948 |
4 | 2018-03-01 00:40:00 | 5.383841 |
何も考えないでプロットした場合
まずは何も考えずに描画してみます。
fig, ax = plt.subplots()
ax.plot(c_df["datetime"], c_df["C1"])
ご覧の通り、日付が重なってしまっています。
軸ラベルを回転させた場合
今度は、軸ラベルを回転させて描画を行います。
fig, ax = plt.subplots()
ax.plot(c_df["datetime"], c_df["C1"])
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, fontsize=10);
軸ラベルを45度回転させて、重ならないように表示することができました。
解説
今回のポイントは
plt.setp(labels, rotation=45, fontsize=10)
の部分です。
丁寧に書くと、matplotlib.pyplot.setp(obj, *args, **kwards)ですね。
setpは”set property”の略です。
この関数はオブジェクトを第一引数に受け取り、そのオブジェクトにpropertyを付与するような役割を果たします。
今回はget.xticklabels()で回収してきたオブジェクトにrotationとfontsizeを付与しているような形です。
なので、例えば描画対象をオブジェクトとして拾っておけば、色や太さを変えることなどもできます。これは後ほど応用例としてご紹介します。
ちなみに、今回引数で与えたlabelsがどのような中身か確認しておくと、
fig, ax = plt.subplots()
ax.plot(c_df["datetime"], c_df["C1"])
labels = ax.get_xticklabels()
print("Entity of labels is {}".format(labels))
#plt.setp(labels, rotation=45, fontsize=10);
Entity of labels is <a list of 8 Text xticklabel objects>
のように、オブジェクトになっていました。
応用例
setpでグラフの色と透明度を変える
簡単な応用例として、まずは先ほどのグラフの色と透明度を変えてみます。
この例では、plotした際の返り値をlineという変数に格納しています。
fig, ax = plt.subplots()
line = ax.plot(c_df["datetime"], c_df["C1"])
labels = ax.get_xticklabels()
print("Entity of line is {}".format(line))
print("Entity of labels is {}".format(labels))
plt.setp(line, color="k", alpha=0.5)
plt.setp(labels, rotation=45, fontsize=10);
順序が前後しますが、グラフはこちらです。
また、print文の中身はこちらです。
Entity of line is [<matplotlib.lines.Line2D object at 0x116cc7358>]
Entity of labels is <a list of 8 Text xticklabel objects>
目的通り、グラフの色と透明度を変えることができています。
散布図への応用
今度は、散布図に応用してみます。
今回は以下のようなデータフレームを準備しています。
c_df.head()
datetime | C1 | C2 | C3 | |
---|---|---|---|---|
0 | 2018-03-01 00:00:00 | 0.000000 | 1.000000 | 1.000000 |
1 | 2018-03-01 00:10:00 | 1.764052 | 2.331587 | 0.688216 |
2 | 2018-03-01 00:20:00 | 2.164210 | 3.046865 | 1.417220 |
3 | 2018-03-01 00:30:00 | 3.142948 | 1.501465 | 1.635041 |
4 | 2018-03-01 00:40:00 | 5.383841 | 1.493081 | 0.735949 |
単純にプロットした結果がこちら。
fig, ax = plt.subplots(figsize=(5,5))
ax.scatter(c_df["C1"], c_df["C2"])
ax.scatter(c_df["C1"], c_df["C3"])
グラフを見る限り、特に軸ラベルを回転する必要はなさそうです。
しかし、今後の応用を考えて、軸ラベルの回転とプロットの色の変更などを行ってみた結果がこちらです。
fig, ax = plt.subplots(figsize=(5,5))
plot1 =ax.scatter(c_df["C1"], c_df["C2"])
plot2 = ax.scatter(c_df["C1"], c_df["C3"])
xlabels = ax.get_xticklabels()
ylabels = ax.get_yticklabels()
plt.setp(plot1, color="b", alpha=0.5)
plt.setp(plot2, color="k", alpha=0.5)
plt.setp(xlabels, rotation=45, fontsize=10)
plt.setp(ylabels, rotation=45, fontsize=10);
# 以下はタイトルやラベルなどの付与
ax.set_title("Scatter Plot")
ax.set_xlabel("C1")
ax.set_ylabel("Value")
ax.legend(loc="upper right")
いい感じのグラフになりました。
軸ラベルの刻みを変えたグラフ
ついでに、刻み幅を20ではなく10にしたいと思ったので、作成してみました。
fig, ax = plt.subplots(figsize=(5,5))
plot1 =ax.scatter(c_df["C1"], c_df["C2"])
plot2 = ax.scatter(c_df["C1"], c_df["C3"])
new_xticklabel = np.arange(-100, 101, 10)
ax.set_xticks(new_xticklabel)
ax.set_xticklabels(new_xticklabel)
xlabels = ax.get_xticklabels()
ylabels = ax.get_yticklabels()
ax.set_xlim([-80, 40])
plt.setp(plot1, color="b", alpha=0.5)
plt.setp(plot2, color="k", alpha=0.5)
plt.setp(xlabels, rotation=45, fontsize=10)
plt.setp(ylabels, rotation=45, fontsize=10)
# 以下はタイトルやラベルなどの付与
ax.set_title("Scatter Plot")
ax.set_xlabel("C1")
ax.set_ylabel("Value")
ax.legend(loc="upper right")
軸ラベルだけでなく、軸そのものにも変更を加えるところがポイントでしょうか。
ここでは、new_xticklabelという名称で-100から100まで10刻みのnumpy arrayを作成しておき、軸と軸ラベルの両方にその値を使用しています。
まとめ
グラフの軸ラベルを斜めにする方法を紹介しました。
意図的に軸をセットするときは初めからオプションでrotationを入れられることも多いですが、他の方法があると知っておくことも役に立つかと思いますので、機会があれば試していただければと思います。
参考資料
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.setp.html
https://stackoverflow.com/questions/41953648/matplotlib-with-dates-changing-labels-and-ticks-for-monthly-data