📊

Plots.jl入門

10 min read

はじめに

公式ドキュメントのサンプルはどれも難しすぎるように思う. そこで, できるだけ簡単な例を通してPlots.jlに親しむためのノートを作成した.

インストール

Juliaのパッケージモードadd Plotsを実行し, 事前にPlots.jlをインストールしておく必要がある. また, ノート上ではusing Plotsを宣言する.

# using Pkg
# Pkg.add("Plots")
using Plots

ミニマル

plot()に関数名を渡すことで描写できる. 特に指定しなければ(かなり滑らかな)折れ線グラフになる.

plot(sin)

自作関数を渡すこともできる. 関数の宣言方法はこちらを参考にするとよい.

f(x) = x^2
plot(f)

1行で書きたい時は無名関数(Anonymous Function)を渡す.

plot(x->x^2)

2つの配列を渡して, それぞれx軸とy軸の値として折れ線グラフや散布図を描くこともできる.

X = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Y = [0, 1, 0, 2, 0, 4, 0, 8, 0, 4, 4]

plot(X, Y)

追加オプション

タイトルや軸ラベル, マーカーや線の色などを変更したい場合は以下のオプションを書き加えればよい.

説明 省略形 オプション 引数例
タイトル title "", "text"
凡例 label "", "text"
x軸ラベル xlabel "", "text"
y軸ラベル ylabel "", "text"
x軸の描写範囲 xlims (-1,1), (0,2π)
y軸の描写範囲 ylims (-1,1), (0,2π)
枠線と軸 framestyle :box, :semi, :origin, :zerolines, :grid :none
グラフの種類 st seriestype :line, :scatter, :steppre:
線の種類(実線, 破線等) ls linestyle :solid, :dash, :dot
線の透明度 la linealpha 0.0, 0.2, 0.5, 1.0
線の太さ lw linewidth 1, 2, 4
線の色 lc linecolor :red, :green, :blue, "#FF0000"
塗潰しの透明度 fa fillalpha 0.0, 0.2, 0.5, 1.0
塗潰しの色 fc fillcolor :red, :green, :blue, "#FF0000"
マーカーの形 markershape :circle, :square, :hexagon
マーカーの大きさ ms markersize 20
マーカーの透明度 markeralpha 0.0, 0.2, 0.5, 1.0
マーカーの色 mc markercolor :red, :green, :blue, "#FF0000"
マーカーの囲み線の太さ msw markerstrokewidth 1, 2, 4
マーカーの囲み線の透明度 markerstrokealpha 0.0, 0.2, 0.5, 1.0
マーカーの囲み線の色 msc markerstrokecolor :red, :green, :blue, "#FF0000"
マーカーの囲み線の種類(実線, 破線等) markerstrokestyle :solid, :dot
凡例の位置 legend :bottomleft, :topright
凡例の背景の色 background_color_legend :red, "#FF0000", nothing
凡例の枠線の色 foreground_color_legend :red, "#FF0000", nothing
plot(sin, title="title", label="label", xlabel="x", ylabel="y", lc="#FF0000", foreground_color_legend=:blue)

範囲

描写範囲についてはxlims=(min,max)ylims=(min,max)をそれぞれ指定する. 片方だけ指定してもよい.

plot(sin, xlims=(0,2*pi), ylims=(-0.3,1))

散布図

散布図はplot()st=:scatterというオプションを追加するか, scatter()を用いる. 基本的な使い方はplot()と同じである.

plot(sin, st=:scatter)

scatter(sin)

ヒストグラム

配列を渡すことで要素についてのヒストグラムを描くことができる. 下記ではnormed=trueのオプションによって正規化された(総面積が1の)ヒストグラムを描いている.

X = [1, 2, 3, 3, 4, 5, 5]

histogram(X, bins=range(0, 6, step=0.2), normed=true)

一様分布の例:

X = rand(10000)

histogram(X, bins=range(0, 1, step=0.02), normed=true)

正規分布の例:

X = randn(10000)

histogram(X, bins=range(-5, 5, step=0.2), normed=true)

グラフを並べる

等価な書き方を4通り列挙する. それぞれ一長一短があるので, 適宜使い分けてほしい.

plt1 = plot(sin, label="")
plt2 = plot(cos, label="")
plt3 = plot(exp, label="")
plt4 = plot(abs, label="")

plot(plt1, plt2, plt3, plt4, layout = (2, 2))

次の記法ではループが使いやすい.

plt = []

push!(plt, plot(sin, label=""))
push!(plt, plot(cos, label=""))
push!(plt, plot(exp, label=""))
push!(plt, plot(abs, label=""))

plot(plt..., layout = (2, 2))

plot(
    plot(sin, label=""),
    plot(cos, label=""),
    plot(exp, label=""),
    plot(abs, label=""),
    layout = (2, 2)
)

plot(
    plot(x->sin(x), label=""),
    plot(x->cos(x), label=""),
    plot(x->exp(x), label=""),
    plot(x->abs(x), label=""),
    layout = (2, 2)
)

無名関数も同様

plot(
    plot(x->x^1, label=""),
    plot(x->x^2, label=""),
    plot(x->x^3, label=""),
    plot(x->x^4, label=""),
    layout = (2, 2)
)

グラフを重ねる

重ねる場合は, plot!()を使う.

plt = plot(sin, label="sin")
plot!(plt, cos, label="cos")

折れ線グラフと散布図を重ねることもできる.

X = [i for i in 0:10]
Y = sin.(X)

plt = plot(0:0.1:10, sin, label="function")
scatter!(plt, X, Y, label="array")

保存

ファイルに保存する場合は以下のようにサイズと拡張子を指定する. SVGはベクタ画像の中でも扱いやすく, PowerPointでもドラッグ&ドロップすれば貼り付けられる. Zennにアップロードする場合はGIFを推奨する.

plt = plot(sin, size=(420,300), fmt=:svg)
savefig(plt, "plot.svg")
display(plt)

アニメーション

GIFアニメーションを出力することもできる.(FFmpegが必要なのでこちらに従ってインストールし, binフォルダを環境変数のパスに追加する必要がある. なお, Juliaのバージョンを上げたときにUndefVarError: ffmpeg not definedというエラーが出たが, パッケージモードで再度add Plotsbuild Plotsを実行すれば動くようになった(参考).)

anim = Animation()

for i in 1:10
    plt = plot(x->sin(i*x), title="i = "*string(i), label="")
    frame(anim, plt)
end

gif(anim, "plot.gif", fps = 2)

Tips

凡例を非表示にする例:

plot(sin, label="")

無名関数の描写の例:

plot(x->x*sin(x^2), label="")

グラフをループで重ねる:

plt = plot()
for i in 1:10
    plot!(plt, x->exp(-x^(2*i)), label=string(i), legend=:topleft, xlim=(-2,2))
end
plot(plt)

グラフをループで並べる:

plt = []
for i in 1:9
    push!(plt, plot(x->sin(x)^i, title=string(i), label=""))
end
plot(plt...)

ここで利用した"splat"について補足する. 以下を実行した結果からprintln(A[1],A[2],A[3],A[4])println(A...)が等価な記法だとわかる.

A = [3,4,5,6]
println(A[1],A[2],A[3],A[4])
println(A...)
println(A)
3456
3456
[3, 4, 5, 6]

折れ線グラフとヒストグラムを重ねる例:

f(x) = exp(-x^2/2) / sqrt(2*pi)
X = randn(1000)
Y = [-0.01-0.0001*i for i in 1:1000]

plt = histogram(X, bins=range(-5,5,step=0.2), ylims=(-0.14,), normed=true, label="Histogram", fa=0.3, fc=1, lc="#FFFFFF")
plot!(plt, f, lw=2, lc="#393e46", label="Exact PDF")

折れ線グラフ, ヒストグラム, 散布図を重ねる例:

f(x) = exp(-x^2/2) / sqrt(2*pi)
X = randn(1000)
Y = [-0.01-0.00005*i for i in 1:1000]

plt = histogram(X, bins=range(-5,5,step=0.2), ylims=(-0.7,), normed=true, label="Histogram", fa=0.3, fc=1, lc="#FFFFFF")
scatter!(plt, X, Y, xlims=(-5,5), ms=1, msw=0, mc="#3261AB", label="Sample")
plot!(plt, f, lw=2, lc="#393e46", label="Exact PDF")

動作環境

versioninfo()
Julia Version 1.6.2
Commit 1b93d53fc4 (2021-07-14 15:36 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, haswell)

参考文献

この記事の元になったJupyter Notebookのデータは下記のリンクにある.

https://gist.github.com/ohno/78d55921c3f88b50a7fb1835be132bcd

この記事に贈られたバッジ

Discussion

ログインするとコメントできます