How do I create a vector with a string and an iterative counter
4 views (last 30 days)
Show older comments
I have a matrix filled with X and Y coordinates that I received from the contour function, that I am going to export to excel and then import into a 3D modeling program. However, I want to be able to name each point after the value of the contour curve and then numerically. (eg, for a curve with the value 600 I would name each point d_600.01, d_600.02, etc.) If I can make a vector with this I can slap it on top of my matrix and then export. Any thoughts?
5 Comments
dpb
on 9 May 2017
Edited: dpb
on 9 May 2017
@Chris, that's what I provided below...
% simplify one of doc contour plots to be small...
y = 0:0.2:2;x=y;
[X,Y] = meshgrid(x,y);
Z = X.*exp(-X.^2-Y.^2);
[C,hC]=contour(X,Y,1000*Z,'levellist',[100 200 300], ...
'showtext','on');
Apply algorithm below to above contour object/array yields following labels
>> [s(1:3);s(end-3:end)] % first/last three...
ans =
'100.01'
'100.02'
'100.03'
'300.07'
'300.08'
'300.09'
'300.10'
>>
for the contour plot above--

ADDENDUM Oh, the above is just the numeric level.point; to add a leading character just put it into the format statement...I'll modify Answer code...
Accepted Answer
dpb
on 8 May 2017
Edited: dpb
on 9 May 2017
"Each contour line definition follows this pattern:"
C(k) = [level x(1) x(2)...
numxy y(1) y(2)... ]
So, you need to parse the array to pick out the various level values and number of points per each and build the name string...following is 'brute force' approach--
[C,hC]=countour(....); % save the handle, too; it's handy
[~,ib]=intersect(C(1,:),hC.LevelList); % find each level start in C
n=0; % counter for each cellstr
for i=ib.' % for each level start position
for j=1:1:C(2,i) % for number points in each countour
n=n+1; % cumulative number of columns
s(n,1}=sprintf('C%3d.%02d',C(1,i),j); % column title string 'Clll.nn'
end
end
Now just string those together into the header string...I forget if can use cellstring in the Excel write or not.
ADDENDUM
Added 'C' as leading character so result will now look like
>> s(1)
ans =
'C100.01'
>> s(end)
ans =
'C300.10'
>>
and Jan's optimization plus fixed a couple typos noticed.
ADDENDUM 2
Came to me...still not perfect but avoids looping over every element inside each group...
s=[]; % accumulator for total array
for i=ib.' % for each level start location in C
s=[s [repmat(C(1,i),1,C(2,i)); 1:C(2,i)]]; % level,point 2D array
end
labls=cellstr(num2str(s.','C%d.%02d')); % and resulting cell array
I'll presume the total length of levels X values isn't so great as to make the dynamic allocation a real bottleneck. I was hung up earlier in that sprintf won't vectorize to memory well; forgetting temporarily that is num2str forte...
Probably somewhere an accumarray and/or bsfun could come into play here as well to expand the single level to the points per level and gather the results, but I'm happy at this point; "exercise for the student" from here on! :)
2 Comments
Jan
on 9 May 2017
s{n,1} = sprintf('C%3d.%02d',C(1,i),j)
is more efficient, because it does not create a scalar cell at first on the right hand side.
More Answers (0)
See Also
Categories
Find more on Surface and Mesh Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!