Is there a way to call a part of a function using an index?

I have a function that I call several times:
plot(position6(1),position6(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position6,'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
Where "position6" is one of N positions defined. Currently, I am manually defining each of them and writing these two lines of code for each position vector (which is in a matrix of vectors). Is there any way to condense this to make it neater, such that I can refer to each instance of the code using the index of the vector matrix? Perhaps with a function?
For example:
myfunc(6)
returns:
plot(position6(1),position6(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position6,'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
Thanks. Here's the full verson of the relevant code segment.
[rows, columns, numberOfColorChannels] = size(img);
figure;
imshow(img);
position1 = [(columns*0.75), (rows*0.5)];
position8 = [(columns*0.75), (rows*0.25)];
position9 = [(columns*0.75), (rows*0.75)];
position2 = [(columns*0.25), (rows*0.5)];
position6 = [(columns*0.25), (rows*0.25)];
position7 = [(columns*0.25), (rows*0.75)];
position3 = [(columns*0.5), (rows*0.5)];
position4 = [(columns*0.5), (rows*0.25)];
position5 = [(columns*0.5), (rows*0.75)];
position = {position1, position2, position3, position4, position5, position6, position7, position8, position9};
hold on;
plot(position{6}(1),position{6}(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position{6},'Radius',100, 'Color', 'w', 'FaceAlpha', 0);

4 Comments

Please don't repost the same question when you've already received some comments and answers in this one. If you feel you need to clarify the question, post comments in this one.
hi @Steven Lord, I have already posted clarifications but to no avail, as you might recall. I was hoping to repost the question because my original question was not about indexing into a matrix, but all the answers were about this. Since none of the answers were to the point even after clarification, I felt the need to repost the question.
@Teshan Rezel: We usually do not delete questions, if they got an answer already. Simply insert a link to the new question by editing the text of your question and mark it by: "[EDITED, better version of the question: ... ] "
Hi @Jan, thank you, I shall do this now!

Sign in to comment.

 Accepted Answer

Reposting as answer:
For the reasons set out in the answer by Steven (and the subsequent comments), numbering your variables in not ideal. If you use arrays, you can index them:
columns = 80;
rows = 24;
[c,r]=ndgrid([0.75 0.25 0.5],[0.5 0.25 0.75]);
position=[columns*c(:) rows*r(:)];
position=mat2cell(position,ones(1,size(position,1)),2);
disp(position.')
{[60 12]} {[20 12]} {[40 12]} {[60 6]} {[20 6]} {[40 6]} {[60 18]} {[20 18]} {[40 18]}
myfun(position{6})
function h=myfunc(pos)
plot(pos(1),pos(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', pos,'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
if nargout==0,clear,end
end

More Answers (1)

Do you mean you want to plot position6(1) versus position6(2) in the first call, position6(3) versus position6(4) in the second, etc.? That's easy, a simple for loop (incrementing by two) would be easiest.
for k = 1:2:10
fprintf("Processing elements %d and %d.\n", k, k+1)
end
Processing elements 1 and 2. Processing elements 3 and 4. Processing elements 5 and 6. Processing elements 7 and 8. Processing elements 9 and 10.
Or do you want to plot position6(1) versus position6(2) in the first call, position7(1) versus position7(2) in the second, position8(1) versus position8(2) in the third, etc.?
If the latter, that approach is strongly discouraged.

13 Comments

hi @Steven Lord, thanks for responding.
It's a user-defined number of calls. For example, if the user selects certain options, then it will call position(6)(1), position(6)(2), position(3)(1), position(3)(2) and position (5)(1), position(5)(2). Which position vectors are used and how many depends on the user selection, upto a max of 9.
I'm trying to make it so that instead of hard-coding each of the 9 options for each possible selection, I'm generating a function or callback that I can refer to a fewer number of times. Does that clarify things? I'm not certain if I'm explaining it well!
Instead of position(3)(1), you should have position(3,1) with position organized as a matrix.
I agree with Matt J.
x = randi(10, 5, 2)
x = 5×2
8 10 8 9 2 4 2 10 6 1
for k = 1:height(x)
v = x(k, :);
fprintf("Processing elements %d and %d.\n", v)
end
Processing elements 8 and 10. Processing elements 8 and 9. Processing elements 2 and 4. Processing elements 2 and 10. Processing elements 6 and 1.
hi @Matt J, I didn't include the whole code...this is basically a copy of a my "test" verison on the live editor, but the main body of the code is on the app designer. On the app designer version, I am indexing to the height and width of the axes upon which the image is displayed.
Live Editor version:
[rows, columns, numberOfColorChannels] = size(img);
figure;
imshow(img);
position1 = [(columns*0.75), (rows*0.5)];
position8 = [(columns*0.75), (rows*0.25)];
position9 = [(columns*0.75), (rows*0.75)];
position2 = [(columns*0.25), (rows*0.5)];
position6 = [(columns*0.25), (rows*0.25)];
position7 = [(columns*0.25), (rows*0.75)];
position3 = [(columns*0.5), (rows*0.5)];
position4 = [(columns*0.5), (rows*0.25)];
position5 = [(columns*0.5), (rows*0.75)];
position = {position1, position2, position3, position4, position5, position6, position7, position8, position9};
hold on;
plot(position{6}(1),position{6}(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position{6},'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
Hi @Steven Lord, I agree that the indexing you and Matt describe is correct, but I'm still not certain that it's doing what the needs to be done...
columns = 80;
rows = 24;
colMultipliers = [0.75; 0.25; 0.5; 0.5; 0.5; 0.25; 0.25; 0.75; 0.75];
rowMultipliers = [0.5; 0.5; 0.5; 0.25; 0.75; 0.25; 0.75; 0.25; 0.75];
positions = [columns*colMultipliers, rows*rowMultipliers]
positions = 9×2
60 12 20 12 40 12 40 6 40 18 20 6 20 18 60 6 60 18
Now work with the rows of the positions matrix.
Hi @Steven Lord, again, thanks for this but I'm not sure this is answering the question. I'm trying to, instead of writing:
plot(position6(1),position6(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position6,'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
Instead, write something like:
function myfunc(x)
...
myfunc(6)
would give:
plot(position6(1),position6(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position6,'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
Is this possible?
It is possible, but you should not be relying on numbered variables. If they are related enough for the numbers to mean anything, that means the numbers are data. Don't store data in a variable name. At the very least they could be a struct array or a cell array.
Hi @Rik, thanks for responding. The code I've shown here is from my "test" version on the live editor. The real version will be what you've mentioned, but I need to know that the concept works first before I know if this is the best route to take. Thank you.
If you don't tell us that position6(1) is actually position{6}(1), how are we supposed to give advice?
Hi @Rik, I posted this earlier,so apologis for not including it in the body of the main post. I'll edit it now.
Here is the relevant code.
[rows, columns, numberOfColorChannels] = size(img);
figure;
imshow(img);
position1 = [(columns*0.75), (rows*0.5)];
position8 = [(columns*0.75), (rows*0.25)];
position9 = [(columns*0.75), (rows*0.75)];
position2 = [(columns*0.25), (rows*0.5)];
position6 = [(columns*0.25), (rows*0.25)];
position7 = [(columns*0.25), (rows*0.75)];
position3 = [(columns*0.5), (rows*0.5)];
position4 = [(columns*0.5), (rows*0.25)];
position5 = [(columns*0.5), (rows*0.75)];
position = {position1, position2, position3, position4, position5, position6, position7, position8, position9};
hold on;
plot(position{6}(1),position{6}(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', position{6},'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
This sounds as simple as:
myfun(position{6})
function h=myfunc(pos)
plot(pos(1),pos(2),'r+', 'MarkerSize', 100, 'Color', 'w');
h = images.roi.Circle(gca,'Center', pos,'Radius',100, 'Color', 'w', 'FaceAlpha', 0);
if nargout==0,clear,end
end
Or am I misunderstanding what it is you want?
hi @Rik, thanks, this works! I needed to call the function before the definition...Please could you repost as an answer and I'll confirm it as the answer to the question?

Sign in to comment.

Categories

Products

Release

R2020b

Asked:

on 22 Mar 2021

Answered:

Rik
on 23 Mar 2021

Community Treasure Hunt

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

Start Hunting!