【RDKit】MolsToGridImage()で複数行のlegendを大きく表示する

# はじめに

RDKitで複数の分子構造を描画する方法の一つとして、`rdkit.Chem.Draw.MolsToGridImage()`があります。`MolsToGridImage()`では分子構造とセットでlegendを表示させることができますが、legendを複数行にした場合、デフォルトの設定ではlegendのフォントサイズが小さくなってしまいます。本記事では、`MolsToGridImage()`でのlegend(を複数行にした場合)のフォントサイズを調整する方法を紹介します。

![before-after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1236393/1943feb0-2c9d-db0f-4ce5-29a170378cbf.png)


# 環境・ライブラリ

- python: 3.12
- rdkit: 2023.09.3

# スクリプト

以下のスクリプトはnotebook上で実行することを想定しています。
(notebookは[Google colaboratory](https://colab.research.google.com/drive/1AjMFiKpvxpXwCqHQQ_Rzi9NelI9VcnNw?usp=sharing)上で公開しています)

## 準備

1. ライブラリのインポート
```python
from rdkit import Chem
from rdkit.Chem import Draw, Descriptors
```

2. 分子の準備（SMILESは[こちら](https://github.com/molecule-generator-collection/ChemTSv2/blob/master/data/ChEMBL_220K.smi)から取得しました）
```python
# smilesのリストを作成
smiles = [
    "C(Cc1nnn[nH]1)c1nnn[nH]1",
    "C1=C(N2CCNCC2)c2nccn2Cc2ccccc21",
    "C1=C(c2ccccc2)Sc2ccccc2-n2cccc21",
    "C1=C(c2ccco2)N2CCN=C2S1",
    "C1=C(c2ccsc2)N2CCN=C2S1",
    "C1=Cc2cccnc2N(C2CC2)c2ncccc21",
]
# Molオブジェクトに変換
mols = [Chem.MolFromSmiles(smi) for smi in smiles]
```

3. 分子を描画する際に使用するlegendの作成
ここでは、分子の通し番号と分子量を2行で表示させるようにします。
```python
mol_id = [f"Mol {i}" for i in range(len(mols))]
mw = [int(Descriptors.MolWt(mol)) for mol in mols]
legends = [f"ID: {mol_id[i]}\nMW: {mw[i]}" for i in range(len(mols))]
```
`legends`の中身
```
['ID: Mol 0\nMW: 166',
 'ID: Mol 1\nMW: 266',
 'ID: Mol 2\nMW: 275',
 'ID: Mol 3\nMW: 192',
 'ID: Mol 4\nMW: 208',
 'ID: Mol 5\nMW: 235']
```

## デフォルト設定で描画

それでは分子を実際に描画します。
まずはデフォルトの設定で描画してみます。

```python
Draw.MolsToGridImage(
    mols,
    molsPerRow=3,
    subImgSize=(200, 200),
    legends=legends,
    useSVG=True,
)
```
フォントサイズがやや小さくなってしまいました。
![mols_default.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1236393/9bbb6852-c576-a460-dbb9-5819df8dcdb0.png)



## legendのフォントサイズを大きくして描画

続いて、legendのフォントサイズを大きくして描画します。
`Draw.MolDrawOptions()`の`legendFontSize`と`legendFraction`の値を調整します。

```python
options = Draw.MolDrawOptions()
options.legendFontSize = 20   # default: 16
options.legendFraction = 0.2   # default: 0.1

Draw.MolsToGridImage(
    mols,
    molsPerRow=3,
    subImgSize=(200, 200),
    drawOptions=options,
    legends=legends,
    useSVG=True,
)
```
フォントサイズを大きくできました！
![mols.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1236393/8c29a072-804f-7765-27c2-4846843126c6.png)


# 解説

`Draw.MolDrawOptions()`で`legendFontSize`と`legendFraction`の値を調整することで、legendの大きさを調整できました。

`legendFontSize`と`legendFraction`の役割は下記の通りです。
- `legendFontSize`: legendのフォントサイズ
- `legendFraction`: legendを表示する領域の大きさ

legendを複数行にした際にフォントサイズが小さくなってしまう原因は、legendを表示する領域の大きさが足りなくなってしまうからのようです。legendがlegendFractionで定義された領域に無理やり押し込むために、文字サイズが小さくなってしまうようです。なので描画する際のコツとしては、`legendFontSize`の値と`legendFraction`の値をバランスよく設定することだと思います。

そもそも`MolsToGridImage()`ではlegendが複数行になることは想定されていないようですね。本当はもう少し細かい調整（行間の調整等）をしたいですが...。引き続き色々試してみようと思います。。（もしやり方をご存知の方がいれば是非教えてください！）

以上です。この記事が少しでも皆さんの助けになれば嬉しいです！


# 参考

- rdkit Issues Feature Request: Multiline legend in MolsToGridImage #3093: https://github.com/rdkit/rdkit/issues/3093
- MolDrawOptionsのドキュメント: https://www.rdkit.org/docs/cppapi/structRDKit_1_1MolDrawOptions.html