pythonのmatplotlibを用いてXRDのデータを発表用グラフにしてみた

# はじめに
pythonのmatplotlibを用いて、XRDのデータをグラフにするプログラムです。
matplotlibの使い方も解説していきます。
出力は以下のようなグラフになります。
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/2a717201-8ff4-8399-d34a-efc0d8c995a8.png)


コマンドライン引数にxyファイルのデータを渡すと、このように発表用のデータになります。
渡すxyファイルの数を変えても、良い感じに調整してくれます。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/a1d0cc5c-509d-70b5-47d3-b18cef6c5b62.png)


# コード
コードは以下のようになります。

```python:xrd_plot.py
import matplotlib.pyplot as plt
import sys


def main():

    plt.rcParams['font.family'] = 'arial'
    plt.rcParams['xtick.direction'] = 'in'  # x axis in
    plt.rcParams['ytick.direction'] = 'in'  # y axis in
    plt.rcParams['font.size'] = 14
    # plot
    fig = plt.figure()
    ax = fig.add_subplot(111)
    for i in range(len(sys.argv)-1):
        f = open(sys.argv[i + 1], 'r')
        x_list = []  # x_listを定義 (空のリストを作成)
        y_list = []  # y_listを定義

        for line in f:
            data = line.split()
            x_list.append(float(data[0]))
            y_list.append(float(data[1]))
        y_list = list(map(lambda x: x - i * 10000, y_list))
        ax.plot(x_list, y_list, linewidth=0.5)

    ax.set_xlabel("2$\it{θ}$ (deg)")
    ax.set_ylabel("intensity (counts)")
    plt.ylim(-(len(sys.argv)-1)*10000, 9000)
    plt.xlim(10, 70)
    plt.tick_params(labelleft=False)
    plt.show()

    # save
    fig.savefig('test.png', bbox_inches="tight", pad_inches=0.05)


if __name__ == "__main__":
    main()
```

# コード解説
それではコードの解説をしていきます。
まず、以下のコードをみていきましょう。

```.py
plt.rcParams['font.family'] = 'arial'
plt.rcParams['xtick.direction'] = 'in'  # x axis in
plt.rcParams['ytick.direction'] = 'in'  # y axis in
plt.rcParams['font.size'] = 14
```
まず、matplotlibは以下のような階層構造をとっていることを理解してください。
matplotlib.pyplotのfigure()やsubplot()などのメソッドを用いて、FigreオブジェクトやAxisオブジェクトを作成することができますが、pyplotのメソッドを使用すると、pyplotを用いて作成した全てのオブジェクトに影響を与えます。そのため、グラフの書式やフォントの大きさなどのグラフ全体に影響を与える設定は、pyplotのメソッドを直接使用します。一つ一つのコードの意味をみていきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/fd196ea9-37b5-efcc-5715-86960bb6d2a7.png)

```.py
plt.rcParams['font.family'] = 'arial'
```
このコードは、グラフ全体の書式を決定しています。今回はarialを使用していますが、必要に応じてTimes New romanなどに変更してください。グラフ全体の何かを変更したい時は、このようにplt.rcParamsを使用します。

```.py
 plt.rcParams['xtick.direction'] = 'in'  # x axis in
    plt.rcParams['ytick.direction'] = 'in'  # y axis in
```

このコードでグラフの目盛りを内向きに変更しています。xtickがX軸を、ytickがＹ軸を表しています。


```.py
plt.rcParams['font.size'] = 14
```
この部分でフォントの大きさを調整しています。今回は14に設定しています。
***
それでは次のコードをみていきましょう。

```.py
fig = plt.figure()
ax = fig.add_subplot(111)
```
このコードで上の図のFigreオブジェクトとAxesオブジェクトを作成しています。
subplotの引数は、(行の数,列の数,何番目に配置しているか)となっています。グラフを複数並列させるときに設定します。縦に二つのグラフを並列させたいときは、行の数が2となり、またグラフをplotするためのaxesオブジェクトが二つ必要になるため、
`ax1 = fig.add_subplot(211) 
 ax2 = fig.add_subplot(212)`
と書けばよいです。また、subplotは引数が二桁ではない場合にはカンマ区切りは必要ありません。
figureオブジェクトは、グラフを保存するときに必要になります。今回の例では、一つのaxesオブジェクトによるplotが同一のfigreオブジェクトに対して行われ、そのグラフのみを保存する必要があるため、figreオブジェクトは一つで十分です。figureオブジェクトのadd_subolotメソッドを用いたことで、axesオブジェクトはfigureオブジェクトに含まれています。
***
それでは次のコードをみていきましょう。

```.py
for i in range(len(sys.argv)-1):
        f = open(sys.argv[i + 1], 'r')
        x_list = []  # x_listを定義 (空のリストを作成)
        y_list = []  # y_listを定義

        for line in f:
            data = line.split()
            x_list.append(float(data[0]))
            y_list.append(float(data[1]))
        y_list = list(map(lambda x: x - i * 10000, y_list))
        ax.plot(x_list, y_list, linewidth=0.5)
```
xyファイルは2列のファイルとなっていて、左がx座標の値、右がy座標の値となっています。また、dataには空白で区切られた文字列が入っているので、splitを用いてリスト型に変換します。そのリストから値を取り出して空のリストに追加していき、ax.plotを用いてplotしていきます。二つ目以降のデータはmap関数を用いてY軸方向に100000ずつずらしていきます。そのため、一番上のデータにコマンドライン引数で渡した最初のデータが出力されます。
***

それでは次のコードをみていきましょう。

```.py
ax.set_xlabel("2$\it{θ}$ (deg)")
ax.set_ylabel("intensity (counts)")
plt.ylim(-(len(sys.argv)-1)*10000, 9000)
plt.xlim(10, 70)
plt.tick_params(labelleft=False)
plt.show()
 # save
fig.savefig('test.png', bbox_inches="tight", pad_inches=0.05)
```

`ax.set_xlabel`は、X軸のラベルを設定しています。θを斜体で表示するために、$\it{}$で挟んでいます。
`plt.ylim`と`plt.xlim`はY軸とX軸の長さを設定しています。Y軸方向は、与えたグラフの数に応じて拡張しています。
また、`plt.tick_params(labelleft=False)`により、Y軸のラベルを無効化しています。
`plt.show()`により、pyplotで作成した全てのオブジェクトを出力し、
`fig.savefig('test.png', bbox_inches="tight", pad_inches=0.05)`を用いて、グラフをtest.pngとして保存します。引数は、グラフを論文用に調整するためのものです。
***
# おわりに
今回はXRDのデータを出力するコードを作成しました。今後、やる気があれば他の実験データを出力するコードも作成していきたいと思います。
ここまで読んで下さり、ありがとうございました。