こんな人にオススメ
plotly
で画像を保存するときに色々と警告とかエラーが出てきて保存できない!指示に従って色々入れても一向に解決しない!助けて!ということで、今回はM1 Macbook Proを購入した執筆者のplotly
の静止画像保存の軌跡についてお話しする。かなり地味な話になるかもしれないが、実はこの静止画保存のために4日くらい費やしてしまった。
なので同じ悩みを持つ人の助けになればということで今回の記事を書く。
Mac、python環境は以下。
- MacBook Pro (13-inch, M1, 2020)
- メモリ16 GB
- macOS Big Sur バージョン 11.2.3(多分)
- Python 3.9.2
- plotly 4.14.3
- plotly-orca 3.4.2
pythonの入れ方
M1チップになったため、巷に溢れているpythonのインストール方法が通用しないという事案が多発していた。一応、自分自身はそういうトラブルを避けるために予めいろいろ調べたのでうまくインストールすることができた。しかし同じくM1 Macbook Proを購入した知人はライブラリがインストールできないか何かを訴えていた。
執筆者が参考にしたサイトは「Osamu Suzuki」さんの「M1 Mac上でPythonの開発環境構築やっていきます」という記事。YouTubeにもなっており、非常にわかりやすく執筆者はトラブルなくインストールすることができた。
plotlyの静止画が保存できない
さて、本題のplotlyの静止画を保存できないという点についての話をしていく。まずはことの発端、次にどういう問題が発生したか、最後に解決策についてお話ししようと思う。
ことの発端
まず、以下のような条件でのみ静止画が保存できなかった。なお、コードの実行には全てVScodeの拡張機能「Code Runner」を使用している。
- 保存可能
- 一度HTMLとしてグラフを作成・表示してから保存ボタンでpng保存
- 保存不可能
- コード内でいきなりpdf、png保存
執筆者自身としては$\TeX$用に画像を使用したかったのでpdfで保存したかった。しかし、一度HTMLでグラフを作成した後に保存する場合の拡張子は「Configuration in Python」にあるようにpng, svg, jpeg, webpのいずれかでpdfがなかった。
config = { 'toImageButtonOptions': { 'format': 'svg', # one of png, svg, jpeg, webp 'filename': 'custom_image', 'height': 500, 'width': 700, 'scale': 1 # Multiply title/legend/axis/canvas sizes by this factor } }
したがって、なんとしてでもコード実行時にpdfとして保存したかった。
パッケージが足りないというエラーコード
まずシンプルに以下のようなコードでpdfとしてグラフを保存しようとした。
fig.write_image('file_name.pdf')
すると以下のようなエラーが吐かれた。
# 省略 ValueError: Image generation requires the psutil package. Install using pip: $ pip install psutil Install using conda: $ conda install psutil
執筆者はconda環境を使用しているので、大人しくconda install psutil
してpsutil
を導入した。Executing transaction: done
という文言が出たのでインストールには成功していたと思われる。
一応ターミナルを再起動して再度グラフを保存すると、次は以下のエラーを吐かれた。
# 省略 ValueError: Image generation requires the requests package. Install using pip: $ pip install requests Install using conda: $ conda install requests
psutil
同様、conda install requests
でrequests
も入れた。こちらもExecuting transaction: done
という文言が出たのでインストールは成功していると思われる。
orca
のパスが通っていない
再度ターミナルを再起動してコードを実行すると以下のエラーが現れた。(username)
には個人個人で使用しているユーザーネームが入る。なお、conda環境はmyenv
もしくはorca_env
で表している。環境を消したり色々してごっちゃになっている。
ValueError: The orca executable is required to export figures as static images, but it could not be found on the system path. Searched for executable 'orca' on the following path: /Users/(username)/miniforge3/envs/orca_env/bin /Users/(username)/miniforge3/condabin /usr/local/bin /usr/bin /bin /usr/sbin /sbin /Library/TeX/texbin If you haven't installed orca yet, you can do so using conda as follows: $ conda install -c plotly plotly-orca Alternatively, see other installation methods in the orca project README at <https://github.com/plotly/orca> After installation is complete, no further configuration should be needed. If you have installed orca, then for some reason plotly.py was unable to locate it. In this case, set the `plotly.io.orca.config.executable` property to the full path of your orca executable. For example: >>> plotly.io.orca.config.executable = '/path/to/orca' After updating this executable property, try the export operation again. If it is successful then you may want to save this configuration so that it will be applied automatically in future sessions. You can do this as follows: >>> plotly.io.orca.config.save() If you're still having trouble, feel free to ask for help on the forums at <https://community.plot.ly/c/api/python>
orca
なるものをインストールしていなかったので、conda install -c plotly plotly-orca
でorca
をインストールしてターミナルを再起動。orca
もExecuting transaction: done
なので正常にインストールできていると思われる。
しかし、またエラーを吐かれた。
ValueError: The orca executable is required in order to export figures as static images, but the executable that was found at '/Users/(username)/miniforge3/envs/orca_env/bin/orca' does not seem to be a valid plotly orca executable. Please refer to the end of this message for details on what went wrong. If you haven't installed orca yet, you can do so using conda as follows: $ conda install -c plotly plotly-orca Alternatively, see other installation methods in the orca project README at <https://github.com/plotly/orca> After installation is complete, no further configuration should be needed. If you have installed orca, then for some reason plotly.py was unable to locate it. In this case, set the `plotly.io.orca.config.executable` property to the full path of your orca executable. For example: >>> plotly.io.orca.config.executable = '/path/to/orca' After updating this executable property, try the export operation again. If it is successful then you may want to save this configuration so that it will be applied automatically in future sessions. You can do this as follows: >>> plotly.io.orca.config.save() If you're still having trouble, feel free to ask for help on the forums at <https://community.plot.ly/c/api/python> Here is the error that was returned by the command $ /Users/(username)/miniforge3/envs/orca_env/bin/orca --help [Return code: 1] node:internal/modules/cjs/loader:927 throw err; ^ Error: Cannot find module 'electron' Require stack: - /Users/(username)/miniforge3/envs/orca_env/lib/node_modules/orca/bin/orca.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:924:15) at Function.Module._load (node:internal/modules/cjs/loader:769:27) at Module.require (node:internal/modules/cjs/loader:996:19) at require (node:internal/modules/cjs/helpers:92:18) at Object.<anonymous> (/Users/(username)/miniforge3/envs/orca_env/lib/node_modules/orca/bin/orca.js:5:84) at Module._compile (node:internal/modules/cjs/loader:1092:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10) at Module.load (node:internal/modules/cjs/loader:972:32) at Function.Module._load (node:internal/modules/cjs/loader:813:14) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12) { code: 'MODULE_NOT_FOUND', requireStack: [ '/Users/(username)/miniforge3/envs/orca_env/lib/node_modules/orca/bin/orca.js' ] }
これだけの文言が並べられて頭がパンクしかけていたが、以前使用していたMacbookでorca
のアプリがあったような気がしていた。したがって、「orca
」と検索してみると、GitHubにそのページが存在していることが判明した。
で、orca自体がHomebrewに存在していた。
brew install --cask orca
上のコードを実行してorcaを入れ、一旦起動してみた。そこで何かMac内のどこかに何かを作る的なポップアップが表示されたような気がした(なんとスクショもメモもせずにすぐに許可したので記録に残っていない)。
ここで、再度グラフをpdfに保存しにコードを実行すると以下のポップアップが出てきた。
これで「許可」を押すかおそらく放置することで画像を保存できた。
ipythonを使用すると保存できない
上で見てきた解決方法はあくまでもVScodeの拡張機能である「Code Runner
」を使用した時の解決方法だ。しかし、Code Runner
の場合はコードを実行するたびにpythonを開いて閉じてなのでmatplotlib
のグラフをぐりぐり動かすことができない。毎回グラフを保存して静止画として扱うしか方法がないのだ。plotly
の場合はブラウザでグラフを開いているので問題ない。
でもサクッとグラフを描けるのはmatplotlib
なのでそこは痛いところ。さらに毎回閉じてしまうのでmatplotlib
でプロットを追加したり軸範囲の変更などの後付けやインタラクティブにプログラム動作確認などを行えない。
執筆者としてはipython
は結構使うのでなんとかして動かしたい。
パスの変更
まず、ipythonを使用しグラフを静止画保存しようとした場合のエラーコードは以下の通り。
ValueError: The orca executable is required in order to export figures as static images, but the executable that was found at '/Users/(username)/miniforge3/envs/myenv/bin/orca' does not seem to be a valid plotly orca executable. Please refer to the end of this message for details on what went wrong. If you haven't installed orca yet, you can do so using conda as follows: $ conda install -c plotly plotly-orca Alternatively, see other installation methods in the orca project README at <https://github.com/plotly/orca> After installation is complete, no further configuration should be needed. If you have installed orca, then for some reason plotly.py was unable to locate it. In this case, set the `plotly.io.orca.config.executable` property to the full path of your orca executable. For example: >>> plotly.io.orca.config.executable = '/path/to/orca' After updating this executable property, try the export operation again. If it is successful then you may want to save this configuration so that it will be applied automatically in future sessions. You can do this as follows: >>> plotly.io.orca.config.save() If you're still having trouble, feel free to ask for help on the forums at <https://community.plot.ly/c/api/python> Here is the error that was returned by the command $ /Users/(username)/miniforge3/envs/myenv/bin/orca --help [Return code: 1] node:internal/modules/cjs/loader:927 throw err; ^ Error: Cannot find module 'electron' Require stack: - /Users/(username)/miniforge3/envs/myenv/lib/node_modules/orca/bin/orca.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:924:15) at Function.Module._load (node:internal/modules/cjs/loader:769:27) at Module.require (node:internal/modules/cjs/loader:996:19) at require (node:internal/modules/cjs/helpers:92:18) at Object.<anonymous> (/Users/(username)/miniforge3/envs/myenv/lib/node_modules/orca/bin/orca.js:5:84) at Module._compile (node:internal/modules/cjs/loader:1092:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10) at Module.load (node:internal/modules/cjs/loader:972:32) at Function.Module._load (node:internal/modules/cjs/loader:813:14) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12) { code: 'MODULE_NOT_FOUND', requireStack: [ '/Users/(username)/miniforge3/envs/myenv/lib/node_modules/orca/bin/orca.js' ] }
この中で注目したのは最後の方にあるrequireStack
の'/Users/(username)/miniforge3/envs/myenv/lib/node_modules/orca/bin/orca.js'
という文章。requireStack
が何なのかは全然わからんが、とりあえずfinderでそのファイルのあるディレクトリまで移動してみた。
そのディレクトリの中身は以下のようになっていて、.js
ファイルの詳細を知らない執筆者は全くわからん状態。
args.js
graph.js
orca.js
orca.electron.js
serve.js
orca.sh
最後のorca.sh
だけ.sh
ファイルで、.sh
ファイルは実行ファイルということを知っていたのでその中身を見てみた。
#!/bin/bash exec "/Applications/orca.app/Contents/MacOS/orca" "$@"
何やらパスが書いてある。そして、パスが関連するエラーは
If you have installed orca, then for some reason plotly.py was unable to locate it. In this case, set the `plotly.io.orca.config.executable` property to the full path of your orca executable. For example: >>> plotly.io.orca.config.executable = '/path/to/orca'
という部分。試しにplotly.io.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
としてコードを書いてみた。するとipython
でもグラフを保存することができた!
実はこの時「よっしゃー!!!」とガッツポーズをとった。
これでCode Runner
を用いてもipython
を用いてもplotly
のグラフを静止画として保存することができた。
ネットワーク受信接続を許可する
これで無事にグラフ画像を保存する事ができたんだけど、画像を保存するたびに上のポップアップが出てきて毎回「許可」を押すのは面倒。ということで、このポップアップが出ないようにする。
ただし、ここで紹介する方法はMacBookのキーチェーン関係になるので自己責任でお願いする。ちなみに執筆者は色々あって一回証明書を削除したら、以下で解説する接続の許可ができなくなった。諦める。
許可するか聴かれなくする方法については以下の流れ。
- 「キーチェーンアクセス」アプリを開く
- 左上のメニューバーから「キーチェーンアクセス」→「証明書アシスタント」→「証明書を作成...」
- 証明書を作成
- 証明書の作成でできた秘密鍵のアクセス許可をする
- 証明書に署名する
- 終了
証明書の作成
まずはキーチェーンアプリを開く。執筆者の場合は⌘ spaceでSpotlightが開くようにしているのでここから検索して開いた。
開いたら左上のメニューバーから「キーチェーンアクセス」→「証明書アシスタント」→「証明書を作成...」と進む。
アシスタントが開けば証明書の名称をつけて、「デフォルトを無効化」にチェックをつける。チェックをすると右下のボタンが「作成」から「続ける」に変わるから続ける。
シリアル番号はそのままにして有効期間は好きにしたらいい。そのまま続ける。証明書情報にメールアドレスを入れてその他は入力してもしなくてもいい。
そのあとは流れに任せて続けるをすれば証明書を作成することができる。
以下のような画面が出たら作成終了。
秘密鍵のアクセス許可をする
次にキーチェーンアクセスアプリで先程の証明書の名称で検索して、引っかかった証明書のうち、秘密鍵を右クリックして「情報を見る」へ進む。
その中の「アクセス制御」タブで「この項目の使用をすべてのアプリケーションに許可」に丸を付けて変更内容を保存。パスワードを求められるのでmacのパスワードを入力。
署名する
最後にターミナルアプリから以下のコードを入力する。この時、パスワードを要求される事があるらしいが執筆者はなかった。
codesign -s "署名(plotly-orca-save-pic)" -f xxx.app --deep
続いて以下のコードを入力し、出力の中のAuthorityに先程の署名(ここだとplotly-orca-save-pic)があることを確認。
codesign -dvv orca.app
最後に以下のコードでvalid on diskが表示されることを確認して終了。
codesign -vv orca.app
執筆者の場合は出たので問題なかったが、出なかった場合の対処方法は執筆者にはわからない。ご自身で調べていただければ幸いだ。執筆者が調べた感じ、情報量が少なすぎて対処できそうになかった。
orca
で画像保存
確認のためにorcaで画像を保存すると、今までのように許可しますかってポップアップが出ずにそのまま画像が保存される。
ただ、許可が自動で反映されるまで処理を待っている(要するに放置し続ける)ような感じで、処理に時間がかかっている気がする。単にポップアップを消しただけのような気もする。
証明書を消したりすると修正できない可能性
執筆者は色々あって一旦、証明書を削除したりorcaを消したりした。そうすると、秘密鍵と公開鍵と証明書が存在しているはずなのに以下のように存在しない判定を喰らって元に戻せなくなった。
The specified item could not be found in the keychain.
なので、もしこの方法を使うのであれば、修正する方法を知っている(もし知っていたら教えてください)か消さない覚悟を持つ必要があるだろう。もしくは執筆者のように諦めるか。
そこはご自身で判断の上、実行するか否か決めていただきたい。
大まかなまとめ
最後にどういう順序でことが進んだのかをまとめる。実際にはこれ以外にも色々インストールしては消しての繰り返しだったが、おそらく今回紹介したことだけで環境は整うと思っている。
Code Runner
plotly
を入れて画像を保存する- 足りないパッケージを提示されたらそれらをインストール
orca
をHomebrew
よりダウンロード- 画像を保存
ipython
Code Runner
の方法に加え、/Users/(username)/miniforge3/envs/env_name/lib/node_modules/orca/bin
的なディレクトリの中の.sh
ファイルの中身を確認- そのファイルに書いているパスを
plotly.io.orca.config.executable
に設定 - 画像を保存する前にこのパスを設定
- 画像保存
面倒だけど一回すればなんとかなる
今回はplotly
で画像を保存するためにorca
の設定をする過程との方法を解説した。しかし、実はorca
は非推奨になりつつあり、今はkaleido
なるものが推されている。orcaの解説にも以下のような記載がある。
As of
plotly
version 4.9, Orca is no longer the recommended way to do static image export. We now recommend Kaleido, as described in the Static Image Export section .
ただ、M1 MacBookのanaconda環境だとkaleido
が競合で入らなくて断念。一応、pip経由で入れることができて問題なかったけど、condaとpipを混ぜるのが嫌だったのでpipから排除した。
まあ、実際に使用できなくなったらkaleido
に移行したらいいと思う。今回の記事が誰かの悩みを解決する一案になれば幸いだ。
関連記事
-
-
【plotly&工夫】楽にグラフを描くためのplotlyの関数化
続きを見る
-
-
【plotly&グラフテーマ】plotly既存のthemasをグラフ化
続きを見る
-
-
【plotly&shapes】レイアウトとしてグラフ内に図形を配置する
続きを見る
-
-
【plotly&3D Mesh】Surfaceプロットを頂点から作成
続きを見る