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

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

annotation*(Plots.jl(GR))

凡例が終わったら次はannotation(注釈文字)。 全くグラフ本体と関係ないものを先に紹介するこのシリーズの真骨頂です。 早速それぞれのアトリビュートについて説明します。

annotations

注釈文字を指定するアトリビュートです。

別名

annotations以外の別名は

  • ann
  • annotate
  • annotation
  • anns

になります。

指定方法

実は公式のPlots.jlのアトリビュートの説明を見ても何が正しい指定方法なのか非常に分かりづらいです。 Unionで表現すると分かりづらいので,私なりに分解しました。 次の4種類が指定可能です。

  1. (x::real, y::real, text:AbstractString)
  2. (x::real, y::real, (args...))
  3. (x::real, y::real, Plots.PlotText)
  4. 上記のTuple型の配列

1.~3.までが(x,y)座標とテキストの指定で,4.は1.~3.の一次元配列になります。

3.の3番目のTupleはPlotText型を指定すればいいのは分かるのですが, 公式ドキュメントの説明にある2.のtext(args...)の中身のTupleというのが今一つぴんとこないと思います。 そこで,PlotText型Plots.text関数について説明します。

PlotText型

PlotText型の定義はcomponents.jl:361あたりで,次の通り。

struct PlotText
    str::AbstractString
    font::Font
end

広義の文字列Font型の複合型で,mutableがついてないので,一応は変化不可です。 ただし,Font型はmutableがついているので,fontの中身,つまりテキストの属性は書き換え可能という感じです。 Font型はlegend_font(|_halign|_valign)(Plots.jl(GR時々PGFPlotsX))で紹介しましたかね。フォントの属性を定義できPlots.font関数で定義可能です。

続いてtext関数の説明です。

text関数

text関数は,Font型に対するfont関数の関係と同じです。 Plots.jlのソース中の定義を確認してみます。

text(t::PlotText) = t
text(t::PlotText, font::Font) = PlotText(t.str, font)
text(str::AbstractString, f::Font) = PlotText(str, f)
text(str, args...; kw...) = PlotText(string(str), font(args...; kw...))
  • PlotText型が引数の時はそのまま引数を返す
  • PlotText型のtFont型のfontが引数の時はtの文字列をfontの属性のPlotText型を返す
  • 広義の文字列型のstrFont型のfが引数の時は文字列がstr,属性がfPlotText型を返す
  • 上記以外の場合,最初の引数を文字列とし,残りの引数をfont関数に渡した属性のPlotText型を返す

という意味になりますかね。

どう指定するのがいいか?

以上のことから,大野 周平さんのPlots.jl入門のように, 素のTuple型を渡すとfont関数でうまく認識できないアトリビュートが発生する恐れがありますね。

素のTuple型を渡した時はfont関数で一生懸命に理解しようと努めてくれます。 ただ,かなり不安定なので属性指定のテキストの場合(x::real, y::real, (args...))で渡すのは避けて,(x::real, y::real, Plots.PlotText)の方が無難ですかね。 いや,分かりやすいのは,Font型を別に定義して,(x::real, y::real, ("テキスト", Font型))が本命ですかね。("テキスト", Font型)をtext関数に渡しても通るからです。

なお,再掲になりますが,Font型,font関数の内容は

  • family
  • pointsize
  • halign
  • valign
  • rotation
  • color

の6つです。

実例

あえて,一度に複数の注釈を設定するものを例にします。 一つだけの場合は,実例のVector型の一つのTupleを指定すればいいだけです。

次の例は全てipagフォントにして,texthalignvaligncolorを変更した 4つを原点を基準として表示しています。

using Plots
gr()
myfont = font(family="ipag")
my_anns = [
    (0.0, 0.0,
     ("右下基準", font(myfont, halign=:right, valign=:bottom, color=:blue))),
    (0.0, 0.0,
     ("左下基準", font(myfont, halign=:left, valign=:bottom, color=:red))),
    (0.0, 0.0,
     ("右上基準", font(myfont, halign=:right, valign=:top, color=:green))),
    (0.0, 0.0,
     ("左上基準", font(myfont, halign=:left, valign=:top, color=:magenta)))
]
plot(sin; annotations=my_anns, gridalpha=0.8)
savefig("annotations-example01.png")

これらのように指定することで,基準の座標を文字列の角に指定することができます。

halignvalignの基準は回転した後の文字列に対してになるようです。

なお,これまでに説明していなかったのですが,GRバックエンドの場合,文字列の途中に\nを 入れることで意図的に改行することができます。

halignにはそれ影響が反映されていて,:rightの場合は右詰め,:hcenterの場合センタリング, :leftの場合は左詰めになります。

using Plots
gr()

myfont=font(family="ipag")
my_anns = [
    (0.0, -1.0, ("下\n基準",
                 font(myfont, halign=:hcenter, valign=:bottom,
                      color=:blue, rotation=0.0))),
    (0.0, 1.0, ("上\n基準",
                font(myfont, halign=:hcenter, valign=:top, color=:red,
                     rotation=180.0))),
    (4.0, 0.0, ("右\n基準",
                font(myfont, halign=:right, valign=:vcenter, color=:green,
                     rotation=90.0))),
    (-4.0, 0.0, ("左\n基準",
                 font(myfont, halign=:left, valign=:vcenter, color=:magenta,
                      rotation=270.0)))
]
plot(sin; annotations=my_anns, gridalpha=0.8, topmargin=(1.0, :cm))
savefig("annotations-example02.png")

sinカーブにそって表示させてみます。valign=:bottomで上側に,valign=:topで下側に表示されます。 文字列は基準を示しています。 傾きをcos関数で求めるため,X, yのアスペクト比を1に固定しています。

using Plots: annotations
using Plots
gr()
fb = font(family="ipag", valign=:bottom, pointsize=8)
ft = font(family="ipag", valign=:top, pointsize=8)
my_anns = [
    [(x, sin(x), ("下", font(fb, rotation=atand(cos(x)))))
     for x in -4.5:0.5:4.5];
    [(x, sin(x), ("上", font(ft, rotation=atand(cos(x)))))
     for x in -4.5:0.5:4.5]
]
plot(sin; annotations=my_anns, size=(1024, 256), aspect_ratio=1.0)
savefig("annotation_sin.png")

annotation(fontfamily|fontsize|halign|valign|rotation|color)

annotation関係のその他のアトリビュートについて説明します。 annotationのフォント関係のそれぞれの属性を変更するものですが, 挙動が少し面白いです。

それは使用例のところで説明します。

別名

一気に例示します。別名は少ないです。 フォントのサイズ指定が~fontsizepointsizeでないところに注意が必要でしょうか?

  • annotationcolor
    • annotationcolors
  • annotationfontfamily
    • annotationfontfamilys
  • annotationfontsize
    • annotationfontsizes
  • annotationhalign
    • annotationhaligns
  • annotationvalign
    • annotationvaligns
  • annotationrotation
    • annotationrotations

使用例

使用例は次の通りです。

注釈として,文字列のみfontを設定したtextの二つありますが, これらのアトリビュートが有効なのは文字列のみを指定したannotationのみに 反映されます。個別に設定したものにはそちらが優先的に利用されるようです。

using Plots
gr()
plot(sin;
     annotations=[(0.0, 0.0, "原点"), (1.0, 0.0, ("点1", font(family="ipam")))], 
     annotationfontfamily="ipag",
     annotationrotation=330,
     annotationhalign=:left,
     annotationvalign=:top,
     annotationfontsize=30,
     annotationcalor=:red)

savefig("annotation_etc.png")

まとめ

以上がannotation関係の内容になります。 記事にするために色々調べてみて,Plots.jlのGRバックエンドの文字列周りの設定要素はこれでほぼ網羅したような気がします。 次は何を調べようか…

指定方法について(追記)

他のアトリビュートについて調べている時に,紹介もれしている指定方法がありました。 (x, y)の代わりに位置を示すシンボル型を指定することが可能のようです。

  1. (loc::Symbol, text:AbstractString)
  2. (loc::Symbol, (args...))
  3. (loc::Symbol, Plots.PlotText)

のような感じで,そのシンボルには

  • :N, NW, :NE, :S :SW, :SE, :W, :E (North, South, West, East)
  • :topleft, :topcenter, :topright, :bottomleft, :bottomcenter, :bottomright

が指定可能です。

説明が手抜きですが使用例です。(使用例も手抜きです)

using Plots
gr()

ann_NSWE = [(s, string(":", s))
            for s in [:N, :NW, :NE, :S, :SW, :SE, :W, :E]]
plt_NSWE = plot(sin; annotations=ann_NSWE,
                title="annotations=\n$ann_NSWE", titlefontsize=8,
                legend=false)
savefig(plt_NSWE, "annotations_NSWE.png")

ann_TBLR = [(s, string(":", s))
            for s in [:topcenter, :bottomcenter,
                      :topleft, :topright,
                      :bottomleft, :bottomright]]

title_TBLR = string("annotation=[", ["$tpl,\n" for tpl in ann_TBLR]..., "]")
plt_TBLR = plot(sin; annotations=ann_TBLR,
                title=title_TBLR, titlefontsize=10,
                legend=false)
savefig(plt_TBLR, "annotations_TBLR.png")

特に利用することもないかもしれませんが,強いていうと:top, :bottom, :left, :right が利用できないことに注意でしょうか。 おそらくはfont[vh]alignと被るからでしょうが,やや不自然な気がします。