在MATLAB中,如何找到所有这些曲线下间隙中最高点的坐标位置?
In MATLAB, how do I find the coordinate position of the highest point in the gap under all these curves?
我有下图,其中绘制了 64 条单独的曲线。这些曲线需要超过一个垂直阈值。 space 超过此阈值的宽度显示为 DoF,并由这两条垂直线定位,可以是曲线最中心部分与阈值相交的任何位置。
我的问题是如何确定垂直线之间和高于阈值但低于所有曲线的区域的最高点?这可能与交叉路口不一致。
曲线没有相同的域(意味着它们的 X 值未对齐)。
我能想到的唯一方法(确实很笨拙)是从左到右遍历 x 值,通过在该 x 值处插入一个点来询问每条曲线,获取所有这些值的最小值,然后移动到下一个 x。这会构建一个最小值列表,然后我选择这些最小值中的最大值。
有没有更聪明的方法来做到这一点?我可以用绘制的数据做到这一点吗?这几乎就像我想构建一个形状,然后找到该形状的最大 y 值。
我采用数值方法,在同一域内重新创建各个曲线并使用相同的增量。这可以通过插值来完成,其中:
newCurve = interp1(origXvalues, origYvalues, newXvalues)
但是我有我使用的曲线的多项式系数,所以我只是重新评估了有界域上的多项式并使用了非常小的增量:
% X domain of interest
minX;
maxX;
% Nx1 Cell array where rows are curve data (polynomial coefficients in this case)
cellArray;
% Pre-populate matrix where columns are curves
matCurves = [];
% Hi-res domain values
newDomain = linspace(minX, maxX, 10000)';
% Cycle through curve sets
for jj = 1:size(cellArray, 1)
% Generate curve based on polynomials bounded within domain
matCurves(:, jj) = polyval(cellArray{jj}, newDomain);
% Or to use interpolation if cellArray had X and Y values as columns
% matCurves(:, jj) = interp1(cellArray{jj, 1}, cellArray{jj, 2}, newDomain);
end
% Find global max of the min of each domain increment
[minValues, idx] = max(min(matCurves, [], 2));
% Path that traces the lowest values within the domain
minValues;
% X value of maximum point below all curves within domain
newDomain(idx);
这对我来说效果很好,而且速度非常快。使用 polyval
或 interp1
循环生成新曲线的时间最长,但对于我的 68 条曲线数据集和生成具有 10000 个点的新曲线,我的开始到完成只用了 0.06 秒第 7 代酷睿 i7 笔记本电脑。
更新:相关问题和解决方案,但不适合我。添加它是为了完整性和其他通过这种方式的人。
在 Mathworks forum 上,有人发布了此代码以标出曲线上所有图的最大值的路径。要做到最小,将最大值更改为最小值:
f=figure;hold on;
plot(rand(10,3))
a=f.Children;
L=a.Children;
D={L.YData};
E=cell2mat(D');
plot(L(1).XData,max(E),'r')
这很聪明。看看它,它不太适合我的数据集,因为它要求曲线已经属于同一个 X 域,而我的不是。此外,我的曲线在图形容器中分组,因此与仅调用 2 个 Children 调用的答案相比,访问它们要困难一些。关于不同的域,请注意这不会产生最小路径:
f=figure;hold on;
plot(sort(rand(10,1)),rand(10,1),'b',sort(rand(10,1)),rand(10,1),'g',sort(rand(10,1)),rand(10,1),'k')
a=f.Children;
L=a.Children;
D={L.YData};
E=cell2mat(D');
plot(L(1).XData,min(E),'r'
总之,为了完整起见,就这些了。
如果你的曲线虽然没有对齐,但在同一个 x
格子上取值(即坐标只能在所有曲线的自由度内取相同的离散值),那么有一个 "simpler" 不涉及插值的解决方案。
为了简单起见,我假设您的曲线是作为 1xn
结构数组 C
给出的,其中包含字段 x
和 y
(其中 n
是曲线的数量),使得C(k).x(i)
是第k
条曲线的第i
坐标:
C =
1xn struct array with fields:
x
y
不同的曲线可以有不同数量的点(即 C(k).x
和 C(p).x
可以有不同的大小),并且它们可能不会对齐。话虽这么说,如果曲线不在同一个 x
格上取值,那么它们需要 resampled 到一个共同的,至少在 "DoF" 的范围内(或像您一样使用插值法不太精确)。
然后,表示Dmin, Dmax
"DoF"的下界和上界,你可以用你提出的最小-最大方法得到红色显示的点:
V = cell(1,n);
for k = 1:n
xk = C(k).x;
V{k} = C(k).y( Dmin <= xk & xk <= Dmax );
% extract those y-values within the DoF
end
% concatenate as a matrix with n rows
V = vertcat(V{:});
max(min(V)) % voila!
我有下图,其中绘制了 64 条单独的曲线。这些曲线需要超过一个垂直阈值。 space 超过此阈值的宽度显示为 DoF,并由这两条垂直线定位,可以是曲线最中心部分与阈值相交的任何位置。
我的问题是如何确定垂直线之间和高于阈值但低于所有曲线的区域的最高点?这可能与交叉路口不一致。
曲线没有相同的域(意味着它们的 X 值未对齐)。
我能想到的唯一方法(确实很笨拙)是从左到右遍历 x 值,通过在该 x 值处插入一个点来询问每条曲线,获取所有这些值的最小值,然后移动到下一个 x。这会构建一个最小值列表,然后我选择这些最小值中的最大值。
有没有更聪明的方法来做到这一点?我可以用绘制的数据做到这一点吗?这几乎就像我想构建一个形状,然后找到该形状的最大 y 值。
我采用数值方法,在同一域内重新创建各个曲线并使用相同的增量。这可以通过插值来完成,其中:
newCurve = interp1(origXvalues, origYvalues, newXvalues)
但是我有我使用的曲线的多项式系数,所以我只是重新评估了有界域上的多项式并使用了非常小的增量:
% X domain of interest
minX;
maxX;
% Nx1 Cell array where rows are curve data (polynomial coefficients in this case)
cellArray;
% Pre-populate matrix where columns are curves
matCurves = [];
% Hi-res domain values
newDomain = linspace(minX, maxX, 10000)';
% Cycle through curve sets
for jj = 1:size(cellArray, 1)
% Generate curve based on polynomials bounded within domain
matCurves(:, jj) = polyval(cellArray{jj}, newDomain);
% Or to use interpolation if cellArray had X and Y values as columns
% matCurves(:, jj) = interp1(cellArray{jj, 1}, cellArray{jj, 2}, newDomain);
end
% Find global max of the min of each domain increment
[minValues, idx] = max(min(matCurves, [], 2));
% Path that traces the lowest values within the domain
minValues;
% X value of maximum point below all curves within domain
newDomain(idx);
这对我来说效果很好,而且速度非常快。使用 polyval
或 interp1
循环生成新曲线的时间最长,但对于我的 68 条曲线数据集和生成具有 10000 个点的新曲线,我的开始到完成只用了 0.06 秒第 7 代酷睿 i7 笔记本电脑。
更新:相关问题和解决方案,但不适合我。添加它是为了完整性和其他通过这种方式的人。
在 Mathworks forum 上,有人发布了此代码以标出曲线上所有图的最大值的路径。要做到最小,将最大值更改为最小值:
f=figure;hold on;
plot(rand(10,3))
a=f.Children;
L=a.Children;
D={L.YData};
E=cell2mat(D');
plot(L(1).XData,max(E),'r')
这很聪明。看看它,它不太适合我的数据集,因为它要求曲线已经属于同一个 X 域,而我的不是。此外,我的曲线在图形容器中分组,因此与仅调用 2 个 Children 调用的答案相比,访问它们要困难一些。关于不同的域,请注意这不会产生最小路径:
f=figure;hold on;
plot(sort(rand(10,1)),rand(10,1),'b',sort(rand(10,1)),rand(10,1),'g',sort(rand(10,1)),rand(10,1),'k')
a=f.Children;
L=a.Children;
D={L.YData};
E=cell2mat(D');
plot(L(1).XData,min(E),'r'
总之,为了完整起见,就这些了。
如果你的曲线虽然没有对齐,但在同一个 x
格子上取值(即坐标只能在所有曲线的自由度内取相同的离散值),那么有一个 "simpler" 不涉及插值的解决方案。
为了简单起见,我假设您的曲线是作为 1xn
结构数组 C
给出的,其中包含字段 x
和 y
(其中 n
是曲线的数量),使得C(k).x(i)
是第k
条曲线的第i
坐标:
C =
1xn struct array with fields:
x
y
不同的曲线可以有不同数量的点(即 C(k).x
和 C(p).x
可以有不同的大小),并且它们可能不会对齐。话虽这么说,如果曲线不在同一个 x
格上取值,那么它们需要 resampled 到一个共同的,至少在 "DoF" 的范围内(或像您一样使用插值法不太精确)。
然后,表示Dmin, Dmax
"DoF"的下界和上界,你可以用你提出的最小-最大方法得到红色显示的点:
V = cell(1,n);
for k = 1:n
xk = C(k).x;
V{k} = C(k).y( Dmin <= xk & xk <= Dmax );
% extract those y-values within the DoF
end
% concatenate as a matrix with n rows
V = vertcat(V{:});
max(min(V)) % voila!