ujimushi(@旧sradjp(15364))の日記

旧スラドの日記の引越先です

legend_position(Plots.jl(GR))

Plots.jlは機能が豊富なわりにドキュメントが少ないことで有名である。 それは同じ機能でも別名がたくさんあったり,同じplot関数でも複雑な記述が可能なためである。

そのため,一つのアトリビュートでもそれなりの分量となるので,1年以上書き続けられるネタになるなぁ と思い,地道に日の日記に残していこうかと思う。(いつまで続くやら…)

一発目はlegend_positionというsubplotsのアトリビュートにしようかと思う。

このシリーズについて

基本的にはGRのバックエンドを用いて, しばらくラインプロットのみを扱っていきたい。その後2Dプロットと進める予定で,3Dプロットは扱わない予定。 というのは使う機会がないからというしごく単純な理由からだ。

plot関数の基本的なところ

2Dの直線プロットの場合は,plot関数を主に使うがまずは次の形になるかと思う。

  • plot(関数)
  • plot(関数, xベクトル)
  • plot(yベクトル)
  • plot(xベクトル, yベクトル)

plot(関数)の場合は自動的に-5から5までの値を入れてグラフにするようだ。 省略するとy1が凡例として示される。

using Plots
plot(sin)

plot(関数, xベクトル)の場合は指定したxベクトルを関数に入れた時のグラフが表示される。 次の例はsin関数に-10から10までの値を入れた時のグラフである。

using Plots
plot(sin, -10:0.1:10)

plot(yベクトル)の場合は,xが1からNまで1ずつ増加するベクトル「1:length(y)」に 指定されたようなグラフとなる。

using Plots
y₁ = rand(11)
plot(y₁)

plot(xベクトル, yベクトル)の場合は,(xₖ,yₖ)を順につないだようなグラフとなる。 個人的には一番よく使う形式である。

using Plots
x₁ = 0:10
y₁ = rand(11)
plot(x₁, y₁)

なお,REPL上からplot(ほげほげ)とすると,グラフが表示されるがこれは 「REPLで実行した結果の値が表示される」 ということで表示されているので,例えば

julia> plot(rand(11));⏎

とかすると,グラフは表示されない。 julia スクリプト.jlで実行させた時はplot関数単体では表示されない。

スクリプト上でグラフを表示させる時はgui関数で表示させた後,キー入力待ち等にしないと 表示した状態を保持しない。最小のサンプルは次のような感じになるだろうか?

#!julia
using Plots
plot(sin)
gui()
println("Hit Enter to finish graph!")
dummy = readline()

legend_positionの例

それではlegend_positionアトリビュートについて思いつく限りのオプションを与えて 一つの図にしてみる。

using Plots
y₁ = rand(11)

plot(
    plot(y₁; legend_position=:outertopleft, title=":outertopleft"),
    plot(y₁; key=:outertop, title=":outertop"), 
    plot(y₁; leg=:outertopright, title=":outertopright"),
    plot(y₁; legend=:topleft, title=":topleft"),
    plot(y₁; legend_positions=:top, title=":top"),  
    plot(y₁; legendposition=:topright, title=":topright"),
    plot(y₁; legendpositions=:left, title=":left"),
    plot(y₁; legends=false, title="false"),
    plot(y₁; legend_position=:right, title=":right"),
    plot(y₁; legend_position=:outerleft, title=":outerleft"),
    plot(y₁; legend_position=(0.5, 0.5), title="(0.5, 0.5)"),
    plot(y₁; legend_position=:outerright,title=":outerright"),
    plot(y₁; legend_position=:bottomleft,title=":bottomleft"),
    plot(y₁; legend_position=:bottom, title=":bottom"),
    plot(y₁; legend_position=:bottomright, title=":bottomright"),
    plot(y₁; legend_position=:outerbottomleft, title=":outerbottomleft"),
    plot(y₁; legend_position=:outerbottom, title=":outerbottom"),
    plot(y₁; legend_position=:outerbottomright, title=":outerbottomright"),
    plot(y₁; legend_position=:none, title=":none"),
    plot(y₁; legend_position=:best, title=":best"),
    plot(y₁; legend_position=:inline, title=":inline"),
    plot(y₁; legend_position=:inside, title=":inside"),
    plot(y₁; legend_position=:legend, title=":legend"),
    plot(y₁; legend_position=(-0.1,-0.1), title="(-0.1, -0.1)"),
    layout=(8,3), size=(1024,1280)
)

legend_position凡例の表示位置 に関するアトリビュートであるが, 全部表示するのは嫌になるぐらいのオプションがあることがお分かりいただけるかと思う。

一つはたくさんの 別名 がある。

  • legend_position
  • key
  • leg
  • legend
  • legend_positions
  • legendposition
  • legendpositions
  • legends

は,別の表現ではあるが,全て同じlegend_positionのオプションを指定するためのキーワードである。 ややこしいことこの上ない。

次にオプションについて,

  • 先頭に:がつくのはSymbol型
  • :outerがつくとグラフ領域の外側に凡例を表示する
  • 上側はtop,左側はleft,右側はright,下側はbottomの意味
  • :bestは自動でそれなりにいい位置を指定(無指定の時のデフォルト)
  • 凡例を表示しないのは:nonefalseを指定した時
  • (x, y)のようなタプル型を指定した時は,グラフ領域の左下が(0,0),右上が(1,1)となる ような位置に凡例を表示する
  • :inlineはラインプロットの横に表示
  • :inside:legendは真ん中に堂々と表示? :insideは上下左右を示すキーワードと組み合わせるのかもしれない

なお,plot関数を上のソースのように指定すると,一つの図の中に複数のグラフを 含むことができる。layout=(8, 3)のところは8行3列のレイアウトにしているという意味である。 subplotの数が24でないとエラーが多分出る。 size=(1024, 1280)は全体の図のサイズを横1024ピクセル,縦1280ピクセルのサイズに設定しているという意味である。

凡例の設定方法よりも前に凡例の位置を指定するオプションの説明をする という計画性のない感じになっているが, どこまでこのシリーズが続けられるか試してみたい。

なおこの情報は,Plots.jlのSubplot Attributesの表の一部をベースとしている。