jupyter notebookのサンプルコードをブログに貼り付ける方法を調べた

このブログを書くときには、jupyter notebookでサンプルのコードを書いて、pythonや各種ライブラリの動作を検証している。

そこでいつも頭を悩ませるのが、「jupyter notebookの上のサンプルコードを、どうやってはてなブログに貼り付けるか?」である。

毎回困っているので、今回は一つ、同じソースコードを色々な方法ではてなブログに挿入してみて、どれが良いか比較してみよう。
なお、現時点ではpandasを使ったデータ処理の説明をすることが多いので、 「DataFrameやSeriesをうまく表示できること」を重視する。
(matplotlib/seabornなどの解説で、図を入れるようになったら、また話が変わってくるのかもしれない。)

f:id:soratokimitonoaidani:20200524133015p:plain 画像はhttps://unsplash.com/photos/Ys-DBJeX0nEより

スクリーンショット(画面キャプチャ)で保存

スクリーンショット(画面キャプチャ)で画像を撮って貼り付ける方法だと、以下のようになる。 はてなブログの記事編集画面から、該当箇所に画像を挿入すればよい。

f:id:soratokimitonoaidani:20200524133120p:plain

ついでにいうと、この記事では上記のjupyter notebookを例に説明する。
中のコードに大した意味はない。[pandas]特定の条件を満たす行を削除する - 子供の落書き帳 Renaissanceで書いたコードを少し改変して、pandasのDataFrameとSeries(行・列)、単一の要素を表示するようにしただけだ。

メリットとデメリット

markdownで保存

jupyter notebookの「File→Download as」の中にはmarkdown書式がある。 はてなブログをいつもmarkdown記法で書いているから、そのまま貼り付ければうまく書式設定されるはずである。やってみよう。

import pandas as pd
df = pd.DataFrame({
    'name'    : ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Fred'],
    'English' : [12, 34, 56, 78, -1, 90],
    'Math'    : [88, 66, -1, 44, 22, -1]    
})
df
name English Math
0 Alice 12 88
1 Bob 34 66
2 Charlie 56 -1
3 David 78 44
4 Eve -1 22
5 Fred 90 -1
df.loc[4, 'English'] = 99999
df.loc[4]
name         Eve
English    99999
Math          22
Name: 4, dtype: object
df['English']
0       12
1       34
2       56
3       78
4    99999
5       90
Name: English, dtype: int64
df.loc[3, 'Math']
44

markdownで保存(ただしPandas.DataFrameの表組みはテキスト表示)

jupyter notebook上で、Pandas.DataFrameの表組みをHTMLで表示するかプレーンテキストで表示するかは、設定で変更できる。
pd.options.display.notebook_repr_html = Trueと書くと、Pandas.DataFrameをきれいにHTMLで表示する(デフォルト)。
pd.options.display.notebook_repr_html = Falseと書くと、Pandas.DataFrameをテキストで表示する。

参考:
[https://note.nkmk.me/python-pandas-option-display/:title]
[https://qiita.com/tanemaki/items/2ed05e258ef4c9e6caac:title]

notebook内にこのコマンドを書いてmarkdown保存した場合は、以下のようになる。

import pandas as pd
pd.options.display.notebook_repr_html = False
df = pd.DataFrame({
    'name'    : ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Fred'],
    'English' : [12, 34, 56, 78, -1, 90],
    'Math'    : [88, 66, -1, 44, 22, -1]    
})
df
      name  English  Math
0    Alice       12    88
1      Bob       34    66
2  Charlie       56    -1
3    David       78    44
4      Eve       -1    22
5     Fred       90    -1

(以降は通常のmarkdown保存と変わらないので省略)

メリットとデメリット

  • メリット
    • 手間がかからない。簡単に見栄えのよい物が作れる。
  • デメリット
    • 入力したコードと実行結果との区別がつきにくい。実行結果が無い(コード入力だけの)セルが続いたときに、どれが入力すべきコードでどれが結果かわからなくなるだろう。
    • 入力したコードと実行結果が一緒になっていない。できれば同じコードブロックの中でコードと実行結果がセットになっているのが一番分かりやすいと思う。
    • 表の表示がイマイチ。何で右端に境界線が出現するの?
      • この問題はプレーンテキストで表示すると解消できる

jupyter notebookを手でコピーペーストして色々いじる

手でコピーペーストしようとしてブラウザ上で「すべて選択」→「コピー」をしても、なぜか入力コード部分だけで、実効結果はコピーされないのよね……。
したがって、出力部分は別途、一つ一つ選択してコピーしてペーストした。

今回は入力コードと出力結果を# ------で区切ることにした。もちろん、別のルールを決めてもよい。

(なお、ブラウザ上のjupyter notebookを元にしたが、markdownをダウンロードして、それを元に手で修正することもできる。)

import pandas as pd
pd.options.display.notebook_repr_html = False  # DataFrameの見栄えをよくするために
df = pd.DataFrame({
    'name'    : ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Fred'],
    'English' : [12, 34, 56, 78, -1, 90],
    'Math'    : [88, 66, -1, 44, 22, -1]    
})
df
# ------
      name  English  Math
0    Alice       12    88
1      Bob       34    66
2  Charlie       56    -1
3    David       78    44
4      Eve       -1    22
5     Fred       90    -1
df.loc[4, 'English'] = 99999
df.loc[4]
# ------
name         Eve
English    99999
Math          22
Name: 4, dtype: object
df['English']
# ------
0       12
1       34
2       56
3       78
4    99999
5       90
Name: English, dtype: int64
df.loc[3, 'Math']
# ------
44

メリットとデメリット

  • メリット
    • 自由度が高い。自分が一番良いと思うスタイルで書ける。
      • 例えば、DataFrameをmarkdownの表組みで書きたければ、その方式で書ける。
    • 入力したコードと実行結果がセットで一緒にできて、対応関係がわかりやすい。
  • デメリット
    • 手間が増える。時間がかかる。面倒。特にコードが多いと労力がかかって辛い。

gistにして貼り付ける

この方法は自分はやったことなかったけど、「jupyter notebook はてなブログ」で検索すると、この方法でやってる人もいるみたい。

詳しい方法については、Jupyter Notebookをはてなブログに貼り付ける方法 - akatak’s blogなどを参照。この記事に従ってgistを作って、それをはてなブログから読み込むと、以下のようになる。

jupyter notebookのサンプルコードをブログに貼り付ける方法を調べた

メリットとデメリット

  • メリット
    • 手間がかからない。簡単に見栄えのよい物が作れる。
  • デメリット
    • スクロールしないと全部見えないので一覧性が悪い。
      • 裏を返せば、コードがだらだら縦に長くならないというメリットでもある。

その他

その他の選択肢

  • 「htmlで保存(File→Download as→HTML (.html))」はダメだ。確かに保存したHTMLファイルを開くときれいにもとのコードが表示される。しかしHTMLファイル内には超大量のCSSがあって、そのおかげでもとの体裁が保持されているのである。これを全部ブログに貼り付けるというのは到底現実的ではない。
  • pythonファイルで保存(File→Download as→Python (.py))」もダメだ。これはPythonスクリプトファイルとして実行できるように保存するものである。コードを実行した結果の表示が全く無いので、今回の目的には不向きである。

他のドキュメントとか

  • scikit-learnの公式サイトのサンプルコードは、コードの状態が切り替えられるようになっている。プロンプト(左端の>>>)と出力とを、見える状態と見えない状態にできるので、入力だけコピーしてすぐに自分の環境で実行できる。すごい。しかし俺には真似できない。

結論

うーん……どれも一長一短だわ……
今までその場その場で適当な方法で記事のコードを作っていたが、 今回改めて各方法を調べてみた。 これが最高という方法が無いということは、よく分かった。
markdownファイルを入力すると、自分が最適だと思うスタイルのコードが出力されるようなスクリプトを作るのが一番良い気がしてきた。「jupyter notebookを手でコピーペーストして色々いじる」のが面倒なので、退屈なことはPythonにやらせよう、というわけでPythonに整形をやらせる方式ね。)

参考文献

「よいサンプルコード」ってどんなサンプルコード? 〜Qiitaや技術ブログを書くときに気を付けること〜 - Qiita
サンプルコード自体の書き方という記事なので、主題は少し違うものの、少し参考になったので書いておく。
例えば「言語の文法として正しいこと」「嘘のコード(実は結果が違ったり動かなかったりするもコード)」のような話が書いてある。
この記事との関連でいうと、「コードの実行結果も一緒に載せること」「コードやエラーメッセージをスクショ(画像)にしないこと」という点が該当する。