I have a question about bar graph in Matlab.
I have this,
a=[20 86 3];
but each number corresponds to one letter like,
20 -->a
86 -->b
3 -->c
and then I make the bar graph,
bar(a)
set(gca,'XTickLabel',{'a','b','c'})
Is there a way to sort a but keep the letter that corresponds to each number?
I thought making a dictionary but I don't know how to make it in MATLAB
Thank you.
Try this,
a = [20 86 3];
l = {'a' , 'b' , 'c'};
[a,ind] = sort(a);
l = l(ind);
When you use [a,ind] = sort(a); the sorted a will be saved in a and the indexes will be saved in ind, which can be used to sort l as well.
Related
I have three cell arrays of strings and I want to find all possible combinations of the three. So if I have:
One= Two= Three=
[A B [M N [W X
C D] O P] Y Z]
I want to be able to find all combinations, which would give me something like:
Four=
[AMW AMX AMY AMZ ANW ANX ANY ANZ AOW AOX AOY AOZ APW APX APY APZ
BMW BMX BMY BMZ BNW BNX BNY BNZ BOW BOX BOY BOZ BPW BPX BPY BPZ
etc.
etc.]
Is there a simple way to do this or will I have to somehow change the strings to integer values?
So, you have three cell arrays:
One = {'A' 'B' 'C' 'D'};
Two = {'M' 'N' 'O' 'P'};
Three = {'W' 'X' 'Y' 'Z'};
We can try to work with their indices
a = 1:length(One);
ind = combvec(a,a,a);
ind would be the matrix with all the combinations of three numbers from 1 to 4, e.g. 111 112 113 114 211 212 213 214 etc. According to combinatorics, its dimensions would be 3x64. The indices correspond to the letters in your cell array, i.e. 214 would correspond to 'BMZ' combination.
EDIT, developed an easy way to generate the combinations without combvec with help of #LuisMendo 's answer:
a=1:4;
[A,B,C] = ndgrid(a,a,a);
ind = [A(:),B(:),C(:)]';
Then you create the blank cell array with length equal to 64 - that's how many combinations of three letters you are expected to get. Finally, you start a loop that concatenates the letters according to the combination in ind array:
Four = cell(1,length(ind(1,:)));
for i = 1:length(ind(1,:))
Four(i) = strcat(One(ind(1,i)),Two(ind(2,i)),Three(ind(3,i)));
end
So, you obtain:
Four =
'AMW' 'BMW' 'CMW' 'DMW' 'ANW' ...
I have 2 cells, B and M. B is nx1 cell and M is a nx2 cell. Some of the values in B are blanks. The rest is the same as M{:,2}. Something like this:
B=
'beta001.img'
'beta002.img'
[]
[]
[]
'beta006.img'
[]
...
And
M=
67 'beta001.img'
89 'beta002.img'
34 'beta003.img'
14 'beta004.img'
15 'beta005.img'
32 'beta006.img'
...
I would like to create a cell C that contains values from the 1st column of M but only if the corresponding values in second column match those in B. Basically, with the example above, C should be:
67
89
32
I can see there are at least two options. The easiest would be doing a horzcat of B and M then get rid of all the rows that contain a blank. I tried:
C=horzcat(B,M);
C=R(~cellfun('isempty',C));
Unfortunately that didn't work. Since I want to learn how to use ismember, the second option is to use that to compare across B and M. Could anyone help me?
Your approach corrected:
This concatenates the matrices. Then extracts the rows, where there aren't any empty entries and then the second column of the result.
C = horzcat(B,M);
C = C(~any(cellfun('isempty',C),2),:);
C = cell2mat(C(:,2));
But you don't need to concatenate the cell-arrays to achieve what you are doing.
Simplified approach:
You can just find the lines where B is not empty, and then take the first column of M of said corresponding lines.
isBnotEmpty = ~cellfun(#isempty, B);
C = cell2mat(M(isBnotEmpty,1));
I am fairly new to matlab. I am sure there is a nice way to do this.
I have the vector h which contains 1257 elements.
And I have the vector t which contains 101 elements.
What I want is to assign the vector t from the 529th to the 630th element from vector h.
I tried this:
h(529:630) = t;
Then I get this message: "In an assignment A(I) = B, the number of elements in B and I must be the same."
If I use a scalar it works. For example:
h(529:630) = 5;
No problem there.
Can someone come up with something clever :)?
Thx
h(529:630) will have 630 - 529 + 1 = 102 elements
>> length(h(529:630))
ans =
102
You must use :
h(530:630) = t ;
Or
h(529:629) = t ;
whatever the case may be.
I was using "intersect" in my Matlab code to do the sorting where I want the following:
[ch] = sort(s, 'ascend');
[same, a] = intersect(s, ch);
For example:
input:
s = [55 21 78 7]
output:
ch = [7 21 55 78]
a = [4 2 1 3]
I need to access a where a shows the original index prior to sorting so I can use it for further processing.
This method works exactly as what I want, but I guess it is taking a lot of time to do the sorting and intersect etc especially when the size of s approaching 100 or higher, are there faster or smarter ways to do so?
Thank you very much.
You can achieve this with
[ch IX] = sort(s, 'ascend')
where IX is identical to a.
I have a cell array A [1x80] in which each element is a cell array itself [9x2].
I have also a vector B representing a group of selected cells of A and I want to extract the element {2,2} of each selected cell.
I tried with a simple
A(1,B){2,2}
but of course it doesn't work....
Can you help me?
How about this:
A = {{1 2; 3 4}, {5 6;7 8}, {9 0; 1 2}; {3 4; 5 6}, {7 8; 9 0}, {11 22; 33 44}};
B = [2,3]
[cellfun(#(x)x(2,2), A){1, B}]
ans =
8 2
EDIT:
The above actually only works in octave. As #Amro points out, to modify it to work in Matlab you need to use a temporary variable:
temp = cellfun(#(x)x(2,2), A);
[temp{1, B}]
or in a one liner (also thanks to #Amro)
cellfun(#(c)c{2,2}, A(1,B))
This answer is the same as #Dan's, but using a simple for loop for performance improvement, if needed.
% If you know that the numel of elements returned by {2,2} will always be one:
nElem = numel(B);
ret(1,nElem)=0;
for k=1:nElem
ret(k) = A{1,B(k)}{2,2}
end
The following answer is wrong, it will only return the {2,2} index from the first element from B
subsref([A{1,B}],struct('type','{}','subs',{{2,2}}))
Which sounds more like what you are doing (and doesn't uses cellfun and arrayfun, that would be better if you are doing this operation on a loop, because they are slow)
See subsref documentation here.
A longer path would be:
temp = [A{1,B}]
temp{2,2}
How about arrayfun(#(x) A{1,x}{2,2}, B)
or (thanks #Amro) cellfun(#(c)c{2,2}, A(1,B))?