概要
前回の記事 で、Blogger の記事を、 Markdown から生成する方法を記載したが、 今回は、グラフの管理方法を記載する。 ただ、方法については、まだまだ模索中であり、 この記事も、随時更新して行くことになりそうだ。
記事によっては、グラフを含めたいことがあるので、 ライブラリを探してみた結果、 Plotly ライブラリが良さそうなので、採用することにした。 このライブラリは、JavaScript にも Python にもパッケージがある。 ただ、Markdown に直接記載できて、 ローカルで結果を直ぐに確認できるような方法は、見当たらない。
最初は、JavaScript のパッケージを利用しようとしたが、 常時読み込むようにすると、サイズが数メガ増えるので、 Blogger では、Plotly を利用しないことにした。 代わりに、Markdown の plotly コードブロックに、 図を生成する Python ソースファイル名を記載し、 Pandoc フィルタで、その Python ソースを実行して図を生成する方式を採用した。
この方式の利点は、図の確認が容易で、使い回しが簡単なことである。
Python 環境を構築する。
ローカルに Python 環境を構築する。 Conda 環境(ここでは Miniconda3)は、導入済みとする。
Python 環境を追加する。
Windows の場合、現時点で kaleido v0.2.1 をインストールすると、 to_image() メソッド呼び出したり、 IntelliJ のターミナルで実行や、ソースコードの実行を行うと show() メソッドが ハングアップするので、v0.1.0.post1 をインストールしている。 WSL の Ubuntu 24.04 上では、0.2.1 でも問題は発生しなかった。
conda create --name plotly -y python=3.12
conda activate plotly
python -m pip install -U pip setuptools wheel
pip install pandas kaleido==0.1.0.post1 pillow plotly panflute
Plotly 用の Pandoc フィルタを作成する。
ファイルの文字コードは、UTF-8 とすること。
[plotly-filter.py
]
import re
import panflute as pf
svg = b""
def action(elem, doc):
if isinstance(elem, pf.CodeBlock) and 'plotly' in elem.classes:
# グラフ描画用の Python ソースをファイルから読み込む。
with open(elem.text.strip(), 'r', encoding='utf-8') as f:
src = f.read()
# .show メソッドの行を、SVG タグ変換処理に置換する。
src = re.sub(r"(.*)\.show\(.*", "global svg\nsvg = \\1.to_image(format='svg')", src)
# SVG タグに変換する処理を実行する。
exec(src)
# Plotly コードブロックを、生成した SVG タグに差し替える。
div = pf.Div(pf.RawBlock(svg.decode()), classes=['ichili-plotly-svg'])
return div
def main(doc=None):
return pf.run_filter(action, doc=doc)
show() メソッドの置換は、以下のようにしている。
fig.show()
↓
global svg
svg = fig.to_image(format='svg')
図を生成する Python ファイルを作成する。
show()
メソッドは必ず記述する。
ただし、関数内には記述しないこと。
ファイルの文字コードは、UTF-8 とすること。
[plot1.py
]
import plotly.express as px
df = px.data.gapminder().query("country=='Canada'")
fig = px.line(df, x="year", y="lifeExp", title='Life expectancy in Canada')
fig.show()
Markdown に Plotly の図を定義する。
Plotly コードブロックの記述は、以下のようにする。 Python のソースファイル名を記述する。
```plotly
plot1.py
```
Markdown を HTML に変換する。
conda activate plotly
pandoc --no-highlight --wrap=preserve --preserve-tabs --mathjax --lua-filter=mermaid-filter.lua --filter=plotly-filter.py 入力.md -o 出力.html
出力した HTML では、Plotly コードブロックに、 SVG タグが生成されているはず。
<div class="ichili-plotly-svg">
<svg class="main-svg"> ・・・ 中略 ・・・
</svg>
</div>
実際の表示は以下のようになる。
IntelliJ の External Tools に登録する場合。
フィルタは、プロジェクトの src/filters に配置している。
項目 | 値 |
---|---|
Name: | to html |
Group: | External Tools |
Program: | cmd |
Arguments: | /c "conda activate plotly & pandoc --no-highlight --wrap=preserve --preserve-tabs --mathjax --lua-filter=$ProjectFileDir$\src\filters\mermaid-filter.lua --filter=$ProjectFileDir$\src\filters\plotly-filter.py $FileName$ -o $FileNameWithoutExtension$.html" |
Working directory: | $FileDir$ |