Gnuplot:具有相关循环索引的嵌套“绘图”迭代(“绘图”)
Gnuplot: Nested “plot” iteration (“plot for”) with dependent loop indices
我最近尝试使用 gnuplot 和 plot for ...
语法在绘图中简明地绘制几个图形。在这种情况下,我需要嵌套循环,因为我想将类似以下索引组合(此处简化)的内容传递给 plot
表达式:
i = 0
、j = 0
i = 1
、j = 0
i = 1
、j = 1
i = 2
、j = 0
i = 2
、j = 1
i = 2
、j = 2
- 等等。
所以 i
从 0
循环到某个上限 N
并且对于 i
的每次迭代,j
从 0
循环到 i
(所以 i <= j
)。我尝试使用以下方法执行此操作:
# f(i, j, x) = ...
N = 5
plot for [i=0:N] for [j=0:i] f(i, j, x) title sprintf('j = %d', j)
但这每次只给出五次 j = 0
的迭代(如 title
所示)。因此,gnuplot 似乎只对 for
表达式求值一次,在开始时固定 i = 0
而不是重新求值以跟上不断变化的 i
值。 this answer 中已经暗示了类似的事情(“在 plot for ...
结构中,第二个索引不能依赖于第一个。”)。
有没有一种简单的方法可以在 gnuplot 中做我想做的事情(即使用上面给出的索引组合和某种循环)?从 gnuplot 4.6 开始就有了 do for { ... }
结构,但是它需要在它的主体中有单独的语句,所以它不能用于 assemble 单个 plot
语句。我想可以使用 multiplot
来解决这个问题,但我想尽可能避免使用 multiplot
,因为它使事情变得比看起来必要的更复杂。
我亲自处理了你的问题。对于您的特定问题,您可以使用数学技巧。将您的索引 (i,j) 重新映射到单个索引 k,这样
(0,0) -> (0)
(1,0) -> (1)
(1,1) -> (2)
(2,0) -> (3)
...
可以证明i与j与k的关系为
k = i*(i+1)/2 + j
可以用一点代数来反转
i(k)=floor((sqrt(1+8.*k)-1.)/2.)
j(k)=k-i(k)*(i(k)+1)/2
现在,您可以在循环中使用单个索引 k
N = 5
kmax = N*(N+1)/2 + N
plot for [k=0:kmax] f(i(k), j(k), x) title sprintf('j = %d', j(k))
我最近尝试使用 gnuplot 和 plot for ...
语法在绘图中简明地绘制几个图形。在这种情况下,我需要嵌套循环,因为我想将类似以下索引组合(此处简化)的内容传递给 plot
表达式:
i = 0
、j = 0
i = 1
、j = 0
i = 1
、j = 1
i = 2
、j = 0
i = 2
、j = 1
i = 2
、j = 2
- 等等。
所以 i
从 0
循环到某个上限 N
并且对于 i
的每次迭代,j
从 0
循环到 i
(所以 i <= j
)。我尝试使用以下方法执行此操作:
# f(i, j, x) = ...
N = 5
plot for [i=0:N] for [j=0:i] f(i, j, x) title sprintf('j = %d', j)
但这每次只给出五次 j = 0
的迭代(如 title
所示)。因此,gnuplot 似乎只对 for
表达式求值一次,在开始时固定 i = 0
而不是重新求值以跟上不断变化的 i
值。 this answer 中已经暗示了类似的事情(“在 plot for ...
结构中,第二个索引不能依赖于第一个。”)。
有没有一种简单的方法可以在 gnuplot 中做我想做的事情(即使用上面给出的索引组合和某种循环)?从 gnuplot 4.6 开始就有了 do for { ... }
结构,但是它需要在它的主体中有单独的语句,所以它不能用于 assemble 单个 plot
语句。我想可以使用 multiplot
来解决这个问题,但我想尽可能避免使用 multiplot
,因为它使事情变得比看起来必要的更复杂。
我亲自处理了你的问题。对于您的特定问题,您可以使用数学技巧。将您的索引 (i,j) 重新映射到单个索引 k,这样
(0,0) -> (0)
(1,0) -> (1)
(1,1) -> (2)
(2,0) -> (3)
...
可以证明i与j与k的关系为
k = i*(i+1)/2 + j
可以用一点代数来反转
i(k)=floor((sqrt(1+8.*k)-1.)/2.)
j(k)=k-i(k)*(i(k)+1)/2
现在,您可以在循环中使用单个索引 k
N = 5
kmax = N*(N+1)/2 + N
plot for [k=0:kmax] f(i(k), j(k), x) title sprintf('j = %d', j(k))