Combining cell array and double vector into sprintf

I would like to create a string for a plot annotation. My needs: Create annotation of the following format:
a1 = number
b1 = number
c1 = number
a2 = number
etc.
Where a1,b1, etc. come from a cell array and the numbers come from a vector. I would do it all manually but I am creating a large number of graphs and the number of coefficients changes between each plot.
What i would like to do is something like the following:
coeffnote = []
for l = 1:length(coeffVals)
coeffnote = [coeffnote, coeffNames(l) ' = ' num2str(coeffVals(l)) '\n'];
coeffnote = string(coeffnote);
end
sprintf(coeffnote(:))
When I run this, I keep getting an error. I am at my wits' end with this. Can anyone help.

回答 (4 件)

Stephen23
Stephen23 2018 年 5 月 18 日
編集済み: Stephen23 2018 年 5 月 18 日

2 投票

You don't need a loop at all, it is simpler without one:
str = {'aa','bb','cc'};
vec = 1:3;
tmp = [str;num2cell(vec)];
out = sprintf('%s = %d\n',tmp{:});

4 件のコメント

David Mueller
David Mueller 2018 年 5 月 18 日
First, thanks for answering. I think this is close, but I am getting weird results:
str =
'a1 = 98
1 = 99
1 = 97
2 = 98
2 = 99
2 = 97
3 = 98
3 = 99
3 = 97
4 = 98
4 = 99
4 = 1.101091e+00
1.883974e+00 = -6.098070e-01
7.002899e-01 = 2.033078e+00
2.452218e+00 = 3.222503e-03
5.724037e+00 = -1.616887e+00
6.268332e-01 = 1.437858e+00
2.806340e+00 = '
This is happening both with my variables and simply copying/pasting your exact code.
Stephen23
Stephen23 2018 年 5 月 18 日
編集済み: Stephen23 2018 年 5 月 18 日
@David Mueller: the code I gave you assumes that both the cell array and numeric vector are row vectors. If they are not then you need to convert them to row, e.g.:
tmp = [str(:).';num2cell(vec(:).')];
The aim is to get a cell matrix shaped like this:
tmp = {'aa','bb','cc',...;
1, 2, 3,...};
This can then be used in sprintf in the way that I showed in my answer. See also:
Note that you might want to change the sprintf format string for the numeric: are the values integer, or decimal fractions? How do you want them formatted?
David Mueller
David Mueller 2018 年 5 月 18 日
Oh okay, I was transposing the wrong one I guess. Thanks! Also - and this is a small matter - is there a simple way to remove the return on the final line?
Stephen23
Stephen23 2018 年 5 月 18 日
編集済み: Stephen23 2018 年 5 月 18 日
"is there a simple way to remove the return on the final line?"
In my experience the simplest way is to put such character/s at the start and remove the first one/s:
out = sprintf('\n%s = %d',tmp{:});
out = out(2:end);
You could do something similar with the last newline, but I find this way easier to follow.

サインインしてコメントする。

Aditya Adhikary
Aditya Adhikary 2018 年 5 月 18 日
編集済み: Aditya Adhikary 2018 年 5 月 18 日

1 投票

Another answer based on your code (not caring about efficiency):
coeffVals = [1,2,3];
coeffNames = {'a1','b1','c1'};
coeffnote = [];
for i = 1:length(coeffVals)
val = coeffVals(i);
name = coeffNames(i);
x = [name,' = ',num2str(val),'\n'];
x = strjoin(x);
coeffnote = [coeffnote, x];
end
sprintf(coeffnote);

2 件のコメント

David Mueller
David Mueller 2018 年 5 月 18 日
Perfect! Thanks! Just out of curiosity, what would a more efficient way be? I feel like Stephen Cobeldick's answer was very close, but giving a weird output.
Jan
Jan 2018 年 5 月 18 日
Letting the output grow iteratively is a bad programming practice in general, because the costs grow exponentially.

サインインしてコメントする。

KSSV
KSSV 2018 年 5 月 18 日

0 投票

x = rand(10,1) ;
y = rand(10,1) ;
plot(x,y,'.r') ;
hold on
str = cell(10,1) ;
for i = 1:10
str{i} = sprintf(['c',num2str(i),'=',num2str(i)]) ;
end
text(x,y,str)

1 件のコメント

Stephen23
Stephen23 2018 年 5 月 18 日
編集済み: Stephen23 2018 年 5 月 18 日
@KSSV: what is the point of using both num2str and sprintf ? Your use of sprintf here does absolutely nothing. This does the same thing:
['c',num2str(i),'=',num2str(i)]
Note that it would be more efficient to use sprintf rather than num2str:
sprintf('c%d = %d',i,i)

サインインしてコメントする。

Guillaume
Guillaume 2018 年 5 月 18 日

0 投票

I'm surprised nobody's mentioned compose which is the modern, more powerful, easier to work with, version of sprintf. Going back to Stephen's example:
str = {'aa','bb','cc'};
vec = 1:3;
compose('%s = %d', string(str(:)), vec(:))
Note that the (:) are to ensure the inputs are column vectors. If they already are, you don't need to bother.

カテゴリ

タグ

質問済み:

2018 年 5 月 18 日

回答済み:

2018 年 5 月 18 日

Community Treasure Hunt

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

Start Hunting!

Translated by