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

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

label(Plots.jl(GR))

今回はSeries Attributesの一つであるlabelで凡例の設定方法について例を示したいと思います。 といっても,ほとんど書く事はないので,複数のデータ列がある時の描画方法の例と併せて例示します。

Seriesは「データ一かたまり」の意味でデータ列に関する属性になります。plot(x,y)xとかyとかも そうです。ただ,実際にx=[...]とかを関数の引数にはできないようです。(私が試した感じでは)

複数データ列での描画方法

まずは,x軸が共通で,3本のデータ列がある時のグラフ描画例について示します。 yに10×3の行列を設定しています。

using Plots
x, y = 1:10, rand(10, 3)
plot(x, y)

x軸を省略すると,x軸に1:length(y)を指定した時のグラフを描画します。 といっても元々1:10なので図としては変わりません。

using Plots
y = rand(10, 3)
plot(y)

関数を複数指定することも可能です。 下の図の3つ目の関数は無名関数を指定している例ですね。

using Plots
plot([sin, cos, x -> 0.1 * x^2 - 1])

複数のVector型を使っての複数データ列の描画も可能です。 おそらく個数の違うデータ列を一度に表示する目的っぽいですね。 ただし,当然ですがそれぞれ対応するxyのデータ数は合わせる必要があります。

ここでは例示しませんが,y₁ , y₂ , y₃に対するxの値がそれぞれ同じ(x₁=x₂=x₃)なら, [x₁, x₂, x₃]の代わりにx₁とすることもできます。

using Plots
x₁, y₁ = 1:12, rand(12)
x₂, y₂ = 1:2:12, rand(6)
x₃, y₃ = 1:3:12, rand(4)
plot([x₁, x₂, x₃], [y₁, y₂, y₃])

凡例の指定方法

本題のlabelの話です。labelの別名はlablabelsと数は少ないです。 今回はlabel=...と指定していますが,lab=...labels=...も同じ意味となります。

3つのデータ列の場合は3列の文字列を設定します。

using Plots
x₁, y₁ = 1:12, rand(12)
x₂, y₂ = 1:2:12, rand(6)
x₃, y₃ = 1:3:12, rand(4)
plot([x₁, x₂, x₃], [y₁, y₂, y₃], label=["A" "B" "C"])

3列 というのがミソで,うっかり 1次元の3つのデータ にしてしまうと次のような図になります。

using Plots
x₁, y₁ = 1:12, rand(12)
x₂, y₂ = 1:2:12, rand(6)
x₃, y₃ = 1:3:12, rand(4)
plot([x₁, x₂, x₃], [y₁, y₂, y₃], label=["A", "B", "C"])

個別に表示しないことも可能です。nothingを指定した例を次の図に示します。その他 空文字列""でも同様の動作をします。

using Plots
x₁, y₁ = 1:12, rand(12)
x₂, y₂ = 1:2:12, rand(6)
x₃, y₃ = 1:3:12, rand(4)
plot([x₁, x₂, x₃], [y₁, y₂, y₃], label=["A" nothing "C"])

言い忘れましたが,label属性のデフォルト値は:autoです。ということは無指定だと 必ず自動で凡例を設定されてしまうので,表示したくない時は""もしくはnothingを指定する 必要があります。

特に一度に凡例を指定する時に問題になることは少ないですが, 後々説明することになると思われるplot!を使う時に忘れていて 勝手に凡例の名前をつけられる,ということが時々起こります。

おっと,忘れていました。LaTeXStringsモジュールを使うことで,凡例にLaTeXの数式を指定することができます。

using Plots, LaTeXStrings
x₁, y₁ = 1:12, rand(12)
x₂, y₂ = 1:2:12, rand(6)
x₃, y₃ = 1:3:12, rand(4)
plot([x₁, x₂, x₃], [y₁, y₂, y₃], label=[L"y_A" L"y_B" L"y_C"])
# plot([x₁, x₂, x₃], [y₁, y₂, y₃], label=[raw"$y_A$" raw"$y_B$" raw"$y_C$"]) # でもOK

labelに数値を指定することも可能なようですが,試したところSymbol型は駄目なようでした。

using Plots
x₁, y₁ = 1:12, rand(12)
x₂, y₂ = 1:2:12, rand(6)
x₃, y₃ = 1:3:12, rand(4)
plot([x₁, x₂, x₃], [y₁, y₂, y₃], label=[true y₂[1] cos(0)*3])

以上が今回紹介する例です。legend_positionに比べると面白みは少ない(?)ですが, データ指定の次ぐらいによく使うattributeではないかと思います。

補足 (2024-02-13 22:00頃追記)

Plots.jlのAttributes Seriesの表によると, labelの型はAbstractStringなので,基本文字型でないとダメです。ただ,なぜ文字型以外でも表示するようにしているかというと, 上の方で自分が間違いの例を出したように凡例をうっかり文字列のVector型で渡した(本当は1行N列の文字列が正解)時に, 「文字列じゃないよ」ってエラーを出すと原因が全く分からないからだと思います。

実際少し前まではエラーだったのが,変な行列っぽいものが表示されるようになったのも覚えがあります。 この変更で凡例の指定をうっかり間違った時に非常に分かりやすくなったと思います。