いい感じのグラフをmatplotlibで作成する

# はじめに
論文やレポートを書く際に、図表はとても大事な要素です．今回は、matplotlibを利用した描き方を解説したいと思います．

自著論文から図を引用します．TeXのソースコードはarXiv上から見ることができますが，使用している図のコードなどは見ることが少ないと思い，今回の記事を書きました．

『Measuring Intrinsic Dimension of Token Embeddings』
リンク：https://arxiv.org/abs/2503.02142

カーネル密度推定の図（本文中図1）
<img width=25%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357670/d897944c-7185-46cf-a8d5-b77cd9b49308.png" width=50%>


ダイナミクスの図（本文中図4）
<img width=25%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357670/1600503d-7243-4010-bcdf-1153f97df44e.png" width=50%>

これは以前，大学のレポートで使ったものです．

2次元カーネル密度推定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357670/41c022b0-e48c-4814-9291-17cd27ef060e.png)


最初に結論として，図1のコードをベタ張りしておきます．データ加工処理は省略します．

```
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import statistics

plt.style.use('default')
plt.rc('font',family='Cambria Math')
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Cambria Math'] + plt.rcParams['font.serif']

plt.figure(figsize=(5, 3))

sns.kdeplot(fasttext_300_filtered, label='FastText', color='blue', fill = True)
sns.kdeplot(google_300_filtered, label='Google News', color='red', fill = True)
sns.kdeplot(glove_300_filtered, label='GloVe', color='green', fill = True)

plt.xlabel('Local Intrinsic Dimension', fontsize=14)
plt.ylabel('Kernel Density', fontsize=14)
plt.xlim((-5, 180))

plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12

plt.grid(color = 'gray', linestyle = '--', linewidth = 0.5, alpha = 0.5, zorder = 0)
plt.legend(fontsize=12)

from matplotlib.backends.backend_pdf import PdfPages

pdf = PdfPages('LID.pdf')
pdf.savefig(bbox_inches='tight', pad_inches = 0.01)
pdf.close()
```

# pdfで出力する

デフォルトだと，pngなどの画像形式で出力されますが，その後TeXで取り組むときはベクタ形式であるべきです．
そのため，pdfで出力されるべきです．

# 色味を気にする

私はグラデーションからサンプリングすることが多いです．

```
plot_color_gradients('Perceptually Uniform Sequential',
                     ['viridis', 'plasma', 'inferno', 'magma', 'cividis'])

plot_color_gradients('Sequential',
                     ['Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
                      'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
                      'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn'])
```

などが用意されています．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357670/2149855d-35c7-4b0d-b3b6-1c55609ddfaf.png)


具体的な色味はここから選ぶといいです．
https://matplotlib.org/stable/users/explain/colors/colormaps.html

たとえば，上の2個目と3個目の図は`GnBu`からサンプリングしています．
これは，2個目の図のコードの一部です．

```
datasequence = [pythia14, pythia70, pythia160, pythia410, pythia1b, pythia1_4b]
cmap = plt.colormaps['GnBu']
colors = cmap(np.linspace(0.35, 1, len(datasequence)))
```

この例であれば，6等分して色を選びます．

# フォントを気にする．

私が以前，先輩から教えていただいたおすすめの設定は次の通りです．
これでTeXの英語の標準フォントに揃います．
```
plt.style.use('default')
plt.rc('font',family='Cambria Math')
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Cambria Math'] + plt.rcParams['font.serif']
```

（Cambria MathはLinux上だと標準サポートされていないという噂を聞いたのですが，テストしていないためこの点は再現不能な場合があるかもしれないです．）

# フォントサイズ

これはかなり出力によって細かく決めています．おすすめは出力ディレクトリをTeXのimageディレクトリにしておくと，TeXのレンダリングによって論文に即反映されるので細かく弄れていいと思います．正直ここはもう少しベストプラクティスがあると思います．

# おわりに
本稿では、（とくに論文執筆における）図の再現性と品質を高めるための具体的なコード例とベストプラクティスをご紹介しました．
これらの手法を組み合わせることで、図の品質と可読性は飛躍的に向上し、読者へのインパクトも強まります．ぜひ試してみてください。