2017-05-17 38 views
1

私は、異なる階段値を使ってODEの解を近似する同じ関数をプロットすることを試みています。私はODEの近似を正しく取得しました。色や凡例を追加する方法は分かりません。プログラムでstat_function()に色と凡例を追加する

私はthis answerをフォローしようとしましたが、関数の数が一定でないコンテキストにはかなりうまく翻訳できません。

ここに私のコードとそれが生成する出力があります。

library(purrr) 
library(ggplot2) 
library(glue) 

eulerMethod = function(f, t0, y0, h, memo = 1000) { 
    vec = double(memo + 1) 

    vec[1] = y0 
    for (i in 1:memo) { 
    vec[i+1] = vec[i] + h*f(t0 + i*h, vec[i]) 
    } 

    solution = function(t) { 
    if (t < t0) return(NaN) 
    n = (t-t0)/h 

    intN = floor(n) 
    if (n == intN) 
     return(vec[n+1]) 
    else # linear interpolation 
     return(vec[intN + 1] + (n - intN) * (vec[intN + 2] - vec[intN + 1])) 
    } 
} 

compare = function(f, t0, y0, interval, hs = c(1, 0.5, 0.2, 0.1, 0.05)) { 
    fs = map(hs, ~ eulerMethod(f, t0, y0, .)) %>% 
    map(Vectorize) 

    # generates "h = 1" "h = 0.5" ... strings 
    legends = map_chr(hs, ~ glue("h = {hs[[.]]}")) 
    map(1:length(hs), ~ stat_function(fun = fs[[.]], 
            geom = "line", 
            aes_(colour = legends[.]))) %>% 
    reduce(`+`, .init = ggplot(data.frame(x = interval), aes(x))) 
} 

# y' = y => solution = exp(x) 
compare(function(t, y) y, 0, 1, c(0, 5)) 

All functions are plotted with the same color and legend.

答えて

1

私は前にglueを使用していないが、それは私はあなたがそれが期待されると思う道を働いていませんでした。それはちょうどh = 1の5つのコピーを戻していた。私は伝説値を作成するためにpaste0を使用するようにコードを変更した:

compare = function(f, t0, y0, interval, hs = c(1, 0.5, 0.2, 0.1, 0.05)) { 
    fs = map(hs, ~ eulerMethod(f, t0, y0, .)) %>% 
    map(Vectorize) 

    # generates "h = 1" "h = 0.5" ... strings 
    legends = paste0("h = ", hs) 

    map(1:length(hs), ~ stat_function(fun = fs[[.]], 
            geom = "line", 
            aes_(colour = legends[.]))) %>% 
    reduce(`+`, .init = ggplot(data.frame(x = interval), aes(x, colour=.))) 
} 

compare(function(t, y) y, 0, 1, c(0, 5)) 

enter image description here

また、コードがもう少し簡単な作ることができる私には思えます。例:

compare = function(f, t0, y0, interval, hs = c(1, 0.5, 0.2, 0.1, 0.05)) { 

    fs = map(hs, ~ eulerMethod(f, t0, y0, .)) %>% 
    map(Vectorize) 

    ggplot(data.frame(x = interval), aes(x)) + 
    map(1:length(fs), function(nn) { 
     stat_function(fun = fs[[nn]], geom = "line", aes_(colour = factor(hs[nn]))) 
    }) + 
    labs(colour="h") 
} 

compare(function(t, y) y, 0, 1, c(0, 5)) 
+0

私はエラーが実際にggplotの機能にないとは思えません。興味のある人には、グルーを使った正しい行は 'legends = glue(" h = {hs} ")'ですが、paste0はこの場合かなりうまくいきます。 –