何时使用转置在 Julia 中绘制等高线
When to use transposition for plotting contour in Julia
所以我尝试使用以下代码通过插值 2D 函数在 Julia 中绘制轮廓:
using Interpolations
using Plots
gr()
xs = 1:0.5:5
ys = 1:0.5:8
# The function to be plotted
f(x, y) = (3x + y ^ 2)
g = Float64[f(x,y) for x in xs, y in ys]
# Interpolate the function
g_int = interpolate(g, BSpline(Quadratic(Line(OnCell()))))
# Scale the interpolated function to the correct grid
gs_int = scale(g_int, xs, ys)
xc = 1:0.1:5
yc = 1:0.1:5
# Compare the real value and the interpolated value of the function at an arbitrary point
println("gs_int(3.2, 3.2) = ", gs_int(3.2, 3.2))
println("f(3.2, 3.2) = ", f(3.2, 3.2))
# Contour of the interpolated plot
p1 = contour(xs, ys, gs_int(xs, ys), fill=true)
# Real contour of the function
p2 = contour(xc, yc, f, fill=true)
plot(p1, p2)
这显然没有给出正确的轮廓,尽管插值看起来是正确的:
问题已通过转置 gs_int(xs, ys)
:
解决
p1 = contour(xs, ys, gs_int(xs, ys)', fill=true)
然后我在 2D 中随机生成一些点 space,并重复相同的过程:
using DelimitedFiles
using Interpolations
using Plots
gr()
data = readdlm("./random_points.txt", Float64)
# Create a dictionary to test different orders of interpolations.
inter = Dict("constant" => BSpline(Constant()),
"linear" => BSpline(Linear()),
"quadratic" => BSpline(Quadratic(Line(OnCell()))),
"cubic" => BSpline(Cubic(Line(OnCell())))
)
x = range(-10, length=64, stop=10)
y = range(-10, length=64, stop=10)
v_unscaled = interpolate(data, inter["cubic"])
v = scale(v_unscaled, x, y)
# The contour of the data points
p0 = contour(x, y, data, fill=true)
display(p0)
# The contour of the interpolated function
p_int = contour(x, y, v(x,y)', fill=true)
display(p_int)
然而,这两个等高线图看起来并不相同。
因为我在 v(x,y)
之后删除了撇号,这有效:
p_int = contour(x, y, v(x,y), fill=true)
现在我不明白了。什么时候应用换位,什么时候不应用?
那是因为在您的第一个示例中您绘制了一个函数,而在第二个示例中您绘制了两个数组。这两个数组不需要转置,因为它们的方向相同。但在第一个示例中,您生成数组的方式相对于 Plots 从您传递的二维函数生成数组的方式进行了转置。
当您绘制一个函数时,Plots 会将结果计算为 g = Float64[f(x,y) for y in ys, x in xs]
而不是相反,就像您在代码中所做的那样。有关绘图中转置的良好讨论,请再次参考 https://github.com/JuliaPlots/Makie.jl/issues/205
所以我尝试使用以下代码通过插值 2D 函数在 Julia 中绘制轮廓:
using Interpolations
using Plots
gr()
xs = 1:0.5:5
ys = 1:0.5:8
# The function to be plotted
f(x, y) = (3x + y ^ 2)
g = Float64[f(x,y) for x in xs, y in ys]
# Interpolate the function
g_int = interpolate(g, BSpline(Quadratic(Line(OnCell()))))
# Scale the interpolated function to the correct grid
gs_int = scale(g_int, xs, ys)
xc = 1:0.1:5
yc = 1:0.1:5
# Compare the real value and the interpolated value of the function at an arbitrary point
println("gs_int(3.2, 3.2) = ", gs_int(3.2, 3.2))
println("f(3.2, 3.2) = ", f(3.2, 3.2))
# Contour of the interpolated plot
p1 = contour(xs, ys, gs_int(xs, ys), fill=true)
# Real contour of the function
p2 = contour(xc, yc, f, fill=true)
plot(p1, p2)
这显然没有给出正确的轮廓,尽管插值看起来是正确的:
问题已通过转置 gs_int(xs, ys)
:
p1 = contour(xs, ys, gs_int(xs, ys)', fill=true)
然后我在 2D 中随机生成一些点 space,并重复相同的过程:
using DelimitedFiles
using Interpolations
using Plots
gr()
data = readdlm("./random_points.txt", Float64)
# Create a dictionary to test different orders of interpolations.
inter = Dict("constant" => BSpline(Constant()),
"linear" => BSpline(Linear()),
"quadratic" => BSpline(Quadratic(Line(OnCell()))),
"cubic" => BSpline(Cubic(Line(OnCell())))
)
x = range(-10, length=64, stop=10)
y = range(-10, length=64, stop=10)
v_unscaled = interpolate(data, inter["cubic"])
v = scale(v_unscaled, x, y)
# The contour of the data points
p0 = contour(x, y, data, fill=true)
display(p0)
# The contour of the interpolated function
p_int = contour(x, y, v(x,y)', fill=true)
display(p_int)
然而,这两个等高线图看起来并不相同。
因为我在 v(x,y)
之后删除了撇号,这有效:
p_int = contour(x, y, v(x,y), fill=true)
现在我不明白了。什么时候应用换位,什么时候不应用?
那是因为在您的第一个示例中您绘制了一个函数,而在第二个示例中您绘制了两个数组。这两个数组不需要转置,因为它们的方向相同。但在第一个示例中,您生成数组的方式相对于 Plots 从您传递的二维函数生成数组的方式进行了转置。
当您绘制一个函数时,Plots 会将结果计算为 g = Float64[f(x,y) for y in ys, x in xs]
而不是相反,就像您在代码中所做的那样。有关绘图中转置的良好讨论,请再次参考 https://github.com/JuliaPlots/Makie.jl/issues/205