ggplot 中的函数图错误地显示为常量线
Plot of a function in ggplot incorrectly showing as a constant line
我想绘制具有给定系数的高次多项式函数。我创建函数 f_erzeuger()
是为了编写多项式函数 f
以便能够使用 ggplot2 和 stat_function(fun = f)
绘制它。 coef
是多项式函数的系数向量。
f_erzeuger <- function(coef) {
f <- function(x) {
x_vec <- c(1, x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10)
d <- length(coef) - 1 # degree of the polynomial
sum(coef * x_vec[1:(d+1)])
}
f
}
但是 ggplot2 无法绘制此曲线,可能是因为该函数实际上并未计算函数项。
f <- f_erzeuger(c(4, 5, 2))
ggplot(data.frame(x = c(-50, 50)), aes(x = x)) +
stat_function(fun = f, color = "blue") +
stat_function(fun = function(x){3 + 5*x + 2*x^2}, color = "red")
f
显示为一条常数线,即使它应该是多项式。
问题是你的函数没有向量化。 运行 ?stat_function
并查看 fun
:
的文档
fun
: Function to use. Either 1) an anonymous function in the base or rlang formula syntax (see rlang::as_function()
) or 2) a quoted or character name referencing a function; see examples. Must be vectorised.
为了使函数矢量化,我们需要确保,例如,f(c(0, 1))
将 return c(f(0), f(1))
。请注意,函数中的一个问题是定义 x_vec = c(1, x, ...)
的行。如果 x
是一个包含多个元素的向量,这将不起作用。
向量化函数的方法有很多种。我将使用 tidyverse(主要是 purrr::map()
)来完成。
f_erzeuger = function(coef) {
function(xvals) {
d = length(coef)
map_dbl(xvals, function(x) {
x_vec = x ^ (0:(d - 1))
sum(coef * x_vec)
})
}
}
此函数的改动:
- 最重要的是,该函数现在已矢量化。
- 我们可以利用 R 中的
^
是矢量化的事实(因此 x^(0:2)
与 c(1, x, x^2)
相同),而不是将 x_vec
明确定义为 10 次.
- 我们可以 return 函数直接在
f_erzeuger()
中,而不是定义 f
然后 return 调用它。
现在事情会按预期进行:
f <- f_erzeuger(c(4, 5, 2))
ggplot(data.frame(x = c(-50, 50)), aes(x = x)) +
stat_function(fun = f, color = "blue") +
stat_function(fun = function(x){3 + 5*x + 2*x^2}, color = "red")
尝试curve
。
f <- f_erzeuger(c(4, 5, 2))
curve(Vectorize(f)(x), -50, 50, col='#c55d0d')
我想绘制具有给定系数的高次多项式函数。我创建函数 f_erzeuger()
是为了编写多项式函数 f
以便能够使用 ggplot2 和 stat_function(fun = f)
绘制它。 coef
是多项式函数的系数向量。
f_erzeuger <- function(coef) {
f <- function(x) {
x_vec <- c(1, x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10)
d <- length(coef) - 1 # degree of the polynomial
sum(coef * x_vec[1:(d+1)])
}
f
}
但是 ggplot2 无法绘制此曲线,可能是因为该函数实际上并未计算函数项。
f <- f_erzeuger(c(4, 5, 2))
ggplot(data.frame(x = c(-50, 50)), aes(x = x)) +
stat_function(fun = f, color = "blue") +
stat_function(fun = function(x){3 + 5*x + 2*x^2}, color = "red")
f
显示为一条常数线,即使它应该是多项式。
问题是你的函数没有向量化。 运行 ?stat_function
并查看 fun
:
fun
: Function to use. Either 1) an anonymous function in the base or rlang formula syntax (seerlang::as_function()
) or 2) a quoted or character name referencing a function; see examples. Must be vectorised.
为了使函数矢量化,我们需要确保,例如,f(c(0, 1))
将 return c(f(0), f(1))
。请注意,函数中的一个问题是定义 x_vec = c(1, x, ...)
的行。如果 x
是一个包含多个元素的向量,这将不起作用。
向量化函数的方法有很多种。我将使用 tidyverse(主要是 purrr::map()
)来完成。
f_erzeuger = function(coef) {
function(xvals) {
d = length(coef)
map_dbl(xvals, function(x) {
x_vec = x ^ (0:(d - 1))
sum(coef * x_vec)
})
}
}
此函数的改动:
- 最重要的是,该函数现在已矢量化。
- 我们可以利用 R 中的
^
是矢量化的事实(因此x^(0:2)
与c(1, x, x^2)
相同),而不是将x_vec
明确定义为 10 次. - 我们可以 return 函数直接在
f_erzeuger()
中,而不是定义f
然后 return 调用它。
现在事情会按预期进行:
f <- f_erzeuger(c(4, 5, 2))
ggplot(data.frame(x = c(-50, 50)), aes(x = x)) +
stat_function(fun = f, color = "blue") +
stat_function(fun = function(x){3 + 5*x + 2*x^2}, color = "red")
尝试curve
。
f <- f_erzeuger(c(4, 5, 2))
curve(Vectorize(f)(x), -50, 50, col='#c55d0d')