プログラミング/julia/グラフの書き方 の履歴(No.12)
更新目次†
Plots を使う†
関数グラフの描画には Plots というライブラリを使う。
これは様々なグラフ描画ライブラリを julia から同一の API で使えるようにするためのラッパーライブラリ。
実際の描画を行う Backend の描画ライブラリとして何を選ぶかによって、描画速度や仕上がりなどが大きく変わってくる。
インストール†
バックエンドのライブラリがないと描画できないので、とりあえず GR も入れておく。
LANG:julia Pkg.add("Plots") Pkg.add("GR") # github の最新版を使うには次のようにする Pkg.checkout("Plots")
バックエンドライブラリ†
実際の描画を行うバックエンドライブラリはいろいろある。
http://docs.juliaplots.org/latest/backends/
例えばバックエンドライブラリとして GR を使うには次のようにする。
LANG:julia using Plots // Plots ライブラリの関数を取り込む Plots.gr() // Plots のバックエンドとして GR を使うことにする gr() // using してあるので、こう書いても同じことになる plot() // GR を使ったグラフが出力される
たぶん、2018春時点で有名なのは GR, Plotly, PyPlot の3つ。
PGFPlots や GLVisualize もまずまず?
各ライブラリの対応表はこちら:
http://docs.juliaplots.org/latest/supported/
それぞれの特徴を独断と偏見でまとめると:
- GR : Plots.gr()
- 出力が svg になるので、印刷したときキレイ
- 点がたくさんあるとブラウザが固まる
- 普段使いにはこれがベスト?
- 3D 表示の一部で x, y パラメータ指定の仕様が他と異なる? surface や wireframe
- 3D 表示の一部に OpenGL を使うため物理ディスプレイなしでは使いづらい? → juliabox でも動かない
- Plotly : Plots.plotly()
- マウスでグラフの表示範囲などを調整可能
- 特に3D表示をぐりぐり動かせるのは圧巻
- 出力が svg になるので、印刷してもキレイ
- 点がたくさんあるとブラウザが固まる
- Gists 上などでは javascript が許可されないためまるっきり表示されない
- jupyter notebook のリロードでもエラーになり画像が表示されない(場合がある?)
- 試行錯誤中は良いのだが、最終版としてはつらい
- PyPlot : Plots.pyplot()
- 出力が png になるため、データ点の多いグラフでも Web ブラウザに負担がかからない
- ただ印刷などすると dpi 不足で画像が粗くなりがち
- インストール時に PyCall の設定が必要(下記参照)
- 一番安定している気がする
- GR が不得意とする 3D 表示や点数の多いグラフではこれがいい
- PGFPlots : Plots.pgfplots()
- 出力が svg になるので、印刷してもキレイ
- 点がたくさんあるとブラウザが固まる
- 3D は対応していないものが多い
- 出力がキレイ(なのか?)
- GLVisualize : Plots.glvisualize()
- OpenGL を使うので高速(?)
- 対応する機能が多い(?)
- ディスプレイドライバが OpenGL に対応していなければならない
- 物理ディスプレイのない環境で動かすのは大変そう(まだ動かせてない)
表示例†
それぞれの表示はこんな感じ。
- PyPlot は一番問題が少ないが、出力は png なので拡大すると粗い
- GD は Surface プロットができない
- Plotly は layout でグラフを複数並べると円グラフや3Dグラフの表示がおかしくなる
- 単体なら問題ない
- PGFPlots は Surface, Pie, WireFrame, HeatMap プロットができない
共通コードはこちら:
各種グラフを書くためのコードサンプルになるはず。
LANG:julia using Plots data1d=rand(10) data1d2=rand(10) data1d3=rand(10) data2d=[rand()/5 + exp(-(x^2+y^2)/100) for x in -10:10, y in -10:10] data1dp=0:2pi/10:2pi; function example(no3d=false,forpgf=false) plot( plot(data1d), plot(data1d,xscale=:log10,yscale=:log10), plot(data1d,seriestype=:steppre), plot(data1d,seriestype=:step), plot(data1d,seriestype=:scatter), plot(data1d,seriestype=:bar), forpgf ? plot() : plot(data1d,seriestype=:pie), plot(data2d,seriestype=:contour,legend=:none), plot(data2d,seriestype=:contour,fill=true,legend=:none), no3d ? plot() : plot(data2d,seriestype=:surface,legend=:none), forpgf ? plot() : plot(data2d,seriestype=:wireframe), forpgf ? plot() : plot(data2d,seriestype=:heatmap,legend=:none), plot(data1dp,data1d,proj=:polar), plot(data1d,data1d2,data1d2,seriestype=:scatter3d), plot(data1d,data1d2,data1d2), plot([0,1,0,-1],[-1,0,1,0],seriestype=:shape), layout=(4,4),size=(800,800),legend=:none ) end
PyPlot†
GR†
Plotly†
あまりにひどいので、表示のおかしなものをすべて取り去ったところこうなった。
複数グラフを layout で並べて表示するのが不得意なだけで、 ここでおかしかったものも単体で表示する分にはまともに表示される。
対数スケールの軸がキレイに表示されているのは Plotly だけだった。
PGFPlots†
svg vs png†
GR のグラフは拡大してもキレイ
PyPlot のグラフは拡大するとぼやける
Plotly のグラフはインタラクティブに編集できるが・・・†
ぐりぐり動く。
でも、ブラウザ上でリロードするだけで、
Javascript error adding output!
ReferenceError: Plotly is not defined
See your browser Javascript console for more details.
などというエラーが出てグラフが表示されなくなってしまう。
Gist 上でも無理。
nbviewer でもダメだった。
http://nbviewer.jupyter.org/gist/osamutake/88c0d0676fe659df23769d2bdbcc21b6
gist から nbviewer への飛び方†
ちょっとオフトピだけど・・・
gist 上で .ipynb を見たとき、右上に θ マークが表示されている場合があり、 そこにカーソルを合わせると nbviewer へのリンクが出るのだけれど、
これをクリックしてもうまく nbviewer に繋がらない。
本来なら
http://nbviewer.jupyter.org/gist/osamutake/da4856f49e025e4646214a0ce690ba06
へ飛ぶべきが、
へ飛んでしまう。
たぶん、github に入れた .ipynb ファイルからだとうまく行くんだと思う。
github の文字を gist に直し、/blob/ 以下を削除すれば良いのだけれど、 もっと簡単には http://nbviewer.jupyter.org/ に gist の URL を入れることで本来のページに飛べる。
バックエンドライブラリのインストール†
結構いろいろ大変。
先人達の足跡を探すのに非常に時間がかかる。。。
GR のインストール†
LANG:console $ julia julia> Pkg.add("GR")
これだけでOK
GLVisualize のインストール†
Web ブラウザから jupyter 経由で使えるようにインストールしたかったのですが、現時点ではできてません。
LANG:console $ julia julia> Pkg.add("GLVisualize ") ... -- Could NOT find Vulkan (missing: VULKAN_LIBRARY VULKAN_INCLUDE_DIR) -- Using X11 for window creation ... CMake Error at CMakeLists.txt:222 (message): The RandR library and headers were not found julia>^D
OpenGL が必要らしい。
LANG:console $ sudo apt-get install libgl1-mesa-dev パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下のパッケージが自動でインストールされましたが、もう必要とされていません: libdmx-dev libdmx1 libfontconfig1-dev libfontenc-dev libfreetype6-dev libfs-dev libfs6 libice-dev libmirclient-dev libmircommon-dev libmircookie-dev libmircookie2 libmircore-dev libpciaccess-dev libpixman-1-dev libprotobuf-dev libprotobuf9v5 libsm-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxfont-dev libxfont1-dev libxfont2 libxft-dev libxi-dev libxinerama-dev libxkbcommon-dev libxkbfile-dev libxmu-dev libxmu-headers libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86dga-dev mir-client-platform-mesa-dev x11proto-bigreqs-dev x11proto-composite-dev x11proto-dmx-dev x11proto-dri3-dev x11proto-fonts-dev x11proto-present-dev x11proto-randr-dev x11proto-record-dev x11proto-render-dev x11proto-resource-dev x11proto-scrnsaver-dev x11proto-video-dev x11proto-xcmisc-dev x11proto-xf86bigfont-dev x11proto-xf86dga-dev x11proto-xf86dri-dev x11proto-xinerama-dev xserver-xorg-dev これを削除するには 'sudo apt autoremove' を利用してください。 以下の追加パッケージがインストールされます: libdrm-amdgpu1 libdrm-common libdrm-dev libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libdrm2 libgl1-mesa-glx libglapi-mesa mesa-common-dev 以下のパッケージが新たにインストールされます: libdrm-common 以下のパッケージはアップグレードされます: libdrm-amdgpu1 libdrm-dev libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libdrm2 libgl1-mesa-dev libgl1-mesa-glx libglapi-mesa mesa-common-dev アップグレード: 10 個、新規インストール: 1 個、削除: 0 個、保留: 26 個。 1,062 kB のアーカイブを取得する必要があります。 この操作後に追加で 616 kB のディスク容量が消費されます。 $ julia julia> Pkg.build("GLVisualize ")
として試したところ、
X11: The DISPLAY environment variable is missing
と言うエラーが出た。
ディスプレイドライバの OpenGL 機能を使ってレンダリングするので、 Web サーバー経由の jupyter からは使えないのかもしれない?
https://github.com/JuliaGL/GLVisualize.jl/issues/146
VirtualGL を使えばできるのかもしれないけれど、ちょっと追い切れなかった。
Plotly のインストール†
juliabox ならそのまま使えるのだけれど、 以下は自分で建てた jupyter サーバーにインストールする場合の話。
https://qiita.com/deaikei/items/b71c1ca2c4c2a2c37526 を見ながら。
julia 上で
LANG: julia Pkg.add("Plotly")
とする前に、python の plotly モジュールを入れておかないとダメ。
LANG:console $ python3 -m pip install plotly $ julia julia> Pkg.add("Plotly")
こうするのが正解。
PyPlot のインストール†
juliabox ならそのまま使えるのだけれど、 以下は自分で建てた jupyter サーバーにインストールする場合の話。
正しい手順はこちら > #e720f643
試行錯誤†
matplotlib を使うので、
LANG:console $ sudo python3 -m pip install matplotlib
とすれば、python から使うのは簡単だった。
julia から使うには、単に Pkg.add("PyPlot") しただけだと、
InitError: Failed to import required Python module matplotlib. For automated matplotlib installation, try configuring PyCall to use the Conda.jl package's Python "Miniconda" distribution within Julia. Relaunch Julia and run: ENV["PYTHON"]="" Pkg.build("PyCall") before trying again. The pyimport exception was: PyError (ccall(@pysym(:PyImport_ImportModule), PyPtr, (Cstring,), name) The Python package matplotlib could not be found by pyimport. Usually this means that you did not install matplotlib in the Python version being used by PyCall. PyCall is currently configured to use the Python version at: python and you should use whatever mechanism you usually use (apt-get, pip, conda, etcetera) to install the Python package containing the matplotlib module. One alternative is to re-configure PyCall to use a different Python version on your system: set ENV["PYTHON"] to the path/name of the python executable you want to use, run Pkg.build("PyCall"), and re-launch Julia. Another alternative is to configure PyCall to use a Julia-specific Python distribution via the Conda.jl package (which installs a private Anaconda Python distribution), which has the advantage that packages can be installed and kept up-to-date via Julia. As explained in the PyCall documentation, set ENV["PYTHON"]="", run Pkg.build("PyCall"), and re-launch Julia. Then, To install the matplotlib module, you can use `pyimport_conda("matplotlib", PKG)`, where PKG is the Anaconda package the contains the module matplotlib, or alternatively you can use the Conda package directly (via `using Conda` followed by `Conda.add` etcetera). ) <type 'exceptions.ImportError'> ImportError('No module named matplotlib',) during initialization of module PyPlot Stacktrace: [1] pyimport_conda(::String, ::String, ::String) at /home/osamu/.julia/v0.6/PyCall/src/PyCall.jl:609 [2] __init__() at /home/osamu/.julia/v0.6/PyPlot/src/init.jl:175 [3] _include_from_serialized(::String) at ./loading.jl:157 [4] _require_from_serialized(::Int64, ::Symbol, ::String, ::Bool) at ./loading.jl:200 [5] _require_search_from_serialized(::Int64, ::Symbol, ::String, ::Bool) at ./loading.jl:236 [6] _require(::Symbol) at ./loading.jl:441 [7] require(::Symbol) at ./loading.jl:405 [8] include_string(::String, ::String) at ./loading.jl:522
と言われ、PyCall を build する必要があった。
正しい手順†
LANG:console $ sudo python3 -m pip install matplotlib $ julia julia> Pkg.add("PyPlot") julia> ENV["PYTHON"]="" julia> Pkg.build("PyCall")
ENV["PYTHON"]="" はシステムの python を使うためのおまじないっぽい?
PGFPlots のインストール†
GR, Plotly, PyPlot は juliabox でもそのまま使えるのだけれど、 PGFPlots は juliabox では使えないため、使いたければ自分で建てた jupyter サーバーにインストールするしかない。
正しい手順はこちら > #beed29ca
試行錯誤†
jupyter の上から Pkg.add("PGFPlots") としたところ、途中で
Installing dependency libmagickwand-6.q16-2 via `sudo apt-get install libmagickwand-6.q16-2`: sudo: 端末 (tty) が存在せず、パスワードを尋ねる (askpass) プログラムが指定されていません =============================[ ERROR: ImageMagick ]============================= LoadError: failed process: Process(`sudo apt-get install libmagickwand-6.q16-2`, ProcessExited(1)) [1] while loading /home/osamu/.julia/v0.6/ImageMagick/deps/build.jl, in expression starting on line 122
というエラーが出た。 そこでコンソールからやってみたら、
LANG:console $ julia julia> Pkg.build("PGFPlots") INFO: Building SpecialFunctions INFO: Building FFTW INFO: Building ImageMagick Installing dependency libmagickwand-6.q16-2 via `sudo apt-get install libmagickwand-6.q16-2`: [sudo] osamu のパスワード: パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下の追加パッケージがインストールされます: ghostscript gsfonts imagemagick-common libcupsfilters1 libcupsimage2 libgs9 libgs9-common libijs-0.35 libjbig2dec0 liblqr-1-0 libmagickcore-6.q16-2 libpaper-utils libpaper1 poppler-data 提案パッケージ: ghostscript-x hpijs fonts-droid texlive-lang-cjk libmagickcore-6.q16-2-extra poppler-utils fonts-arphic-ukai fonts-arphic-uming fonts-nanum 以下のパッケージが新たにインストールされます: ghostscript gsfonts imagemagick-common libcupsfilters1 libcupsimage2 libgs9 libgs9-common libijs-0.35 libjbig2dec0 liblqr-1-0 libmagickcore-6.q16-2 libmagickwand-6.q16-2 libpaper-utils libpaper1 poppler-data アップグレード: 0 個、新規インストール: 15 個、削除: 0 個、保留: 20 個。 12.1 MB のアーカイブを取得する必要があります。 この操作後に追加で 48.1 MB のディスク容量が消費されます。 続行しますか? [Y/n] 中断しました。 ===============================================================================[ ERROR: ImageMagick ]=============================================================================== LoadError: failed process: Process(`sudo apt-get install libmagickwand-6.q16-2`, ProcessExited(1)) [1] while loading /home/osamu/.julia/v0.6/ImageMagick/deps/build.jl, in expression starting on line 122 ==================================================================================================================================================================================== INFO: Building CodecZlib ==================================================================================[ BUILD ERRORS ]================================================================================== WARNING: ImageMagick had build errors. - packages with build errors remain installed in /home/osamu/.julia/v0.6 - build the package(s) and all dependencies with `Pkg.build("ImageMagick")` - build a single package by running its `deps/build.jl` script ====================================================================================================================================================================================
となって、やはりエラー。おしい。
LANG:console $ sudo apt-get install libmagickwand-6.q16-2 $ julia julia> Pkg.build("PGFPlots")
で入った。
でも、plot を呼ぶと
Error saving as SVG could not spawn `lualatex --enable-write18 --output-directory=. tikzpicture`: no such file or directory (ENOENT)
とのエラー。texlive-luatex を入れれば良いのかと思ったのだけれど、
LANG:console $ sudo apt-get install texlive-luatex $ lua^T lua2dox_filter luajittex luaotfload-tool luatex
で、lualatex というコマンドは入らなかった?
http://mickey-happygolucky.hatenablog.com/entry/2016/03/01/234228 を見て、
LANG:console $ sudo apt-get install texlive-lang-cjk lmodern texlive-xetex $ which lualatex /usr/bin/lualatex
これでエラーメッセージが変わって、
Error saving as SVG could not spawn `pdf2svg tikzpicture.pdf tikzpicture.svg`: no such file or directory (ENOENT)
そこで、
LANG:console $ sudo apt-get install pdf2svg
これで正しく動作するようになった。
正しい手順†
LANG:console $ sudo apt-get install libmagickwand-6.q16-2 texlive-luatex texlive-lang-cjk lmodern texlive-xetex pdf2svg $ julia julia> Pkg.add("PGFPlots")
こうかな。
Plots.plot に関数を与えるだけでグラフを書ける†
あまり用例を見ないのだけれど、直接関数を与えてグラフが書ける。とても便利。
ただ今のところ、グラフがカクカクになってしまったときにサンプリング点数を増やす方法が分からなくて困ってる。
@manipulate でインタラクティブにパラメータを変えられる†
Interact モジュールと widget/extension を使う。
実際には、あらかじめパラメータを変えたグラフをすべて用意しておき、 入力値に従って切り替えて表示しているっぽい。
@gif で手軽に GIF アニメが作れる†
@gif を使ってアニメーションをしようとしたところ、
could not spawn `ffmpeg -v 0 -i /tmp/tmpsIoz72/%06d.png -vf palettegen=stats_mode=diff -y /tmp/tmpsIoz72/palette.bmp`: no such file or directory (ENOENT)
と言われた
LANG:console $ sudo apt-get install ffmpeg
@recipe について†
勉強せねば。
https://github.com/JuliaPlots/PlotDocs.jl/blob/master/docs/src/recipes.md
関数のグラフをキレイに描くためのモジュールを作った†
http://nbviewer.jupyter.org/gist/osamutake/9fa7918013c1af17c50666bafb3469d0
このあたりを見る?†
Plots/GR: グラフ package のおすすめ
http://www.cas.cmc.osaka-u.ac.jp/~paoon/misc/julia/post/trouble-plots-package/
JupyterでJuliaを動かして回帰分析をやってみる。
https://qiita.com/kenmatsu4/items/b77ecec75418cbaa2212
jupyter notebookで触れるプロットを描く
http://ksknw.hatenablog.com/entry/2016/08/04/233103
Julia言語と Plots + GR で複素関数のgifアニメーションを作る
http://optie.hatenablog.com/entry/2018/03/29/210619
GR - examples
http://docs.juliaplots.org/latest/examples/gr/
PlotThemes
https://github.com/JuliaPlots/PlotThemes.jl
PGFPlots.ipynb
http://nbviewer.jupyter.org/github/sisl/PGFPlots.jl/blob/master/doc/PGFPlots.ipynb