How do I create a vector with a string and an iterative counter

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

@Jan Simon: I am not sure that Christopher Albert is trying to create variables in the workspace. The description seems to be a kind of header for exporting to an Excel workbook.
@Stephen: Maybe. "name each point after the value of the contour curve and then numerically" sounds like a mixture of data and naming scheme. "d_600.02" is not a useful header also for the same reasons why "d_600dot02" would be a bad name of a variable.
It is not clear to me, what "make a vector with this" means. @Christopher: Further explanations would be useful.
I am analyzing contours of data representing a two dimensional cross section of a fluid. I need to export the contour lines, from the C matrix calulated in [C,h]=countourf(), into excel and then import the excel sheet into a 3D modeling program to create splines corresponding to the contours. I need to be able to uniquely identify the points(I have over 1400) so that I can more easily create a macro to spline them together. I need a letter or string to be at the start of the name, and I would like to include the information about the Z value of the contour in the identifier (contour of velocity 600, 800, etc.) to differentiate between the curves.
Most of the macros I have been looking at for the CAD program recomend a unique identifier column, x column, and y column.
@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...

Sign in to comment.

 Accepted Answer

"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

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.
True dat, just wrote on fly and pasted.
What would be better would be to eliminate the inner loop entirely, but my brain cramped... :(

Sign in to comment.

More Answers (0)

Asked:

on 8 May 2017

Edited:

dpb
on 9 May 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!