Julia/Plots로 플롯 이미징 과정을 추구합니다.

알고 싶은 것


using Plots

plt = plot([sin, cos])
savefig(plt, "sincos.png")



위의 예에서 플롯을 이미징하는 과정을 자세히 살펴 보겠습니다.
plt 의 내부 구조도 신경이 쓰이는 곳이지만, 그 점에 대해서는 기회를 바꾸고 싶다.

output.jl



savefig


savefig(plt, "sincos.png")

파일명의 확장자에 따라서, 대응하는 함수 (이 경우는 png )에 처리를 건네준다.

png


png(plt, "sincos.png")

PNG 의 MIME 를 갖게 해 Base.show 에 처리를 건네준다.

바세. 처w



htps : // 기주 b. 코 m/쥬아아 Pぉts/P㎉ts. jl/bぉb/마s r/src/오우 t푸 t. jl#L210
(다양한 MIME에 대한 메타 프로그래밍으로 정의됨)
io = open("sincos.png", "w")
show(io, MIME("image/png"), plt)

본래는 이름대로 표시를 목적으로 한 함수이다.
htps : // / cs. 주아아 g. rg/엔/v1/바세/이오네와 ぉrk/#바세. 쇼 웬 p ぇ

파일에의 기입은 IO 에 데이터를 흘려 넣는다고 하는 처리이며, 표시와 공통화할 수 있으므로, Base.show 로 정리해 계약하고 있는 것일 것이다.
prepare_output (뷰포인트 설정?) 후, 내부 함수 _show 에 처리를 건네준다.

-
【보충】
예를 들어,
plt = plot([sin, cos])

등으로 직접 플롯이 표시되는 경우도, 암묵적으로 불리는 display(plt) 로부터 이 show 에 처리가 이양된다.

backends/gr.jl



내부 함수 _show 에 대해 설명한다.
htps : // 기주 b. 코 m/쥬아아 Pぉts/P㎉ts. jl/bぉb/마s r/src/바c 켄 ds/gr. jl#L1968

백엔드에 따른 분기



_show 에서는, 백엔드 마다 처리가 분기한다. 백엔드의 정보를 plt 변수의 형태 파라미터로 보관 유지해, 다중 디스패치 하고 있다.
typeof(plt)
# Result: Plots.Plot{Plots.GRBackend}

_show(io, MIME("image/png"), plt)

# backends/gr.jl
function _show(io::IO, ::MIME{Symbol("image/png")}, plt::Plot{GRBackend})
    # 省略
end

본 기사에서는 백엔드를 GR로서 진행해 나가지만, 다른 백엔드에서도 각각 _show가 정의되고 있다. 플롯시에는, 백엔드에 대응한 _show 메소드가 불리게 된다. 각 백엔드에서 _show의 정의는 backends 디렉토리에 포함되어 있습니다.

_show의 정의를 얻는다.



그대로는 읽기 어렵기 때문에 quote 로 둘러싸 보간하자.
htps : // / cs. 주아아 g. 오 rg / 엔 / v1 / 마누아 l / 메타 p 로g 라민 g / # 어서 r 푸치 온 1
mime, fmt = "image/png" => "png"

quote
    function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GRBackend})
        GR.emergencyclosegks()
        filepath = tempname() * "." * $fmt
        env = get(ENV, "GKSwstype", "0")
        ENV["GKSwstype"] = $fmt
        ENV["GKS_FILEPATH"] = filepath
        gr_display(plt, $fmt)
        GR.emergencyclosegks()
        write(io, read(filepath, String))
        rm(filepath)
        if env != "0"
            ENV["GKSwstype"] = env
        else
            pop!(ENV,"GKSwstype")
        end
    end
end

출력의 quote 를 제외하고, 적당하게 코멘트를 추가했다.
function _show(io::IO, ::MIME{Symbol("image/png")}, plt::Plot{GRBackend})
    GR.emergencyclosegks()
    filepath = tempname() * "." * "png"  # データのやり取りに使用する一時ファイル名
    env = get(ENV, "GKSwstype", "0")     # 設定の退避
    ENV["GKSwstype"] = "png"             # フォーマットを環境変数で設定
    ENV["GKS_FILEPATH"] = filepath       # 出力ファイル名も同様
    gr_display(plt, "png")               # プロットを画像化して一時ファイルに保存
    GR.emergencyclosegks()
    write(io, read(filepath, String))    # 画像を読み出して IO に出力
    rm(filepath)                         # 一時ファイルを削除
    if env != "0"
        ENV["GKSwstype"] = env           # 設定を元に戻す
    else
        pop!(ENV, "GKSwstype")
    end
end

GR 환경 변수를 사용한 설정 목록
htps : // gr-f 라메를 rk. 오 rg / 엔 ゔ ぃ 론 멘 t_ ゔ ぁ 리아 b ぇ s. HTML

좋은 웹페이지 즐겨찾기