Matrix being divided by a value unexpectedly - matlab

Just working on multiply 2 rows of a matrix and making the answer another row within the same matrix. However when putting the new row in the matrix all of the values are for some reason divided by 1.0e+03.
X = (M(1,1:5) .* M(2,1:5));
M(3,1:5) = X(1,1:5)
disp(X)
Actual Result
X =
1.0e+03 *
0.4000 0.5500 0.7000 0.5000 0.6000
0.0030 0.0005 0.0008 0.0015 0.0050
1.2000 0.2750 0.5250 0.7500 3.0000
Expected Result
400.0000 550.0000 700.0000 500.0000 600.0000
3.0000 0.5000 0.7500 1.5000 5.0000
1200 275 525 750 3000

Related

Matlab: Inserting copies of the previous rows, them applying a pattern to 2 columns

Another question from the thick guy (me)... apologies - help much appreciated!
Here is an example sample from a larger matrix
0 1.0000 1.0000 60.0000 100.0000 0 0.2500
0 1.0000 1.0000 62.0000 100.0000 0.2500 0.2500
0 1.0000 1.0000 63.0000 100.0000 0.5000 0.2500
1.0000 1.0000 1.0000 58.0000 100.0000 0.7500 0.2500
1.0000 1.0000 1.0000 59.0000 100.0000 1.0000 0.2500
1.0000 1.0000 1.0000 65.0000 100.0000 1.2500 0.2500
2.0000 1.0000 1.0000 55.0000 100.0000 1.5000 0.2500
2.0000 1.0000 1.0000 57.0000 100.0000 1.7500 0.2500
2.0000 1.0000 1.0000 60.0000 100.0000 2.0000 0.2500
3.0000 1.0000 1.0000 54.0000 100.0000 2.2500 0.2500
3.0000 1.0000 1.0000 55.0000 100.0000 2.5000 0.2500
3.0000 1.0000 1.0000 59.0000 100.0000 2.7500 0.2500
4.0000 1.0000 1.0000 55.0000 100.0000 3.0000 0.2500
4.0000 1.0000 1.0000 56.0000 100.0000 3.2500 0.2500
4.0000 1.0000 1.0000 60.0000 100.0000 3.5000 0.2500
5.0000 1.0000 1.0000 53.0000 100.0000 3.7500 0.2500
5.0000 1.0000 1.0000 54.0000 100.0000 4.0000 0.2500
5.0000 1.0000 1.0000 59.0000 100.0000 4.2500 0.2500
6.0000 1.0000 1.0000 53.0000 100.0000 4.5000 0.2500
6.0000 1.0000 1.0000 56.0000 100.0000 4.7500 0.2500
6.0000 1.0000 1.0000 58.0000 100.0000 5.0000 0.2500
7.0000 1.0000 1.0000 58.0000 100.0000 5.2500 0.2500
7.0000 1.0000 1.0000 60.0000 100.0000 5.5000 0.2500
7.0000 1.0000 1.0000 65.0000 100.0000 5.7500 0.2500
8.0000 1.0000 1.0000 53.0000 100.0000 6.0000 0.2500
8.0000 1.0000 1.0000 54.0000 100.0000 6.2500 0.2500
8.0000 1.0000 1.0000 63.0000 100.0000 6.5000 0.2500
9.0000 1.0000 1.0000 61.0000 100.0000 6.7500 0.2500
9.0000 1.0000 1.0000 62.0000 100.0000 7.0000 0.2500
9.0000 1.0000 1.0000 65.0000 100.0000 7.2500 0.2500
etc....
For every z (the value of z has been prescribed earlier in the code) rows I'd like 3 copies of the rows to be inserted verbatim beneath them as follows (in this example z = 3) :
0 1.0000 1.0000 60.0000 100.0000 0 0.2500
0 1.0000 1.0000 62.0000 100.0000 0.2500 0.2500
0 1.0000 1.0000 63.0000 100.0000 0.5000 0.2500
0 1.0000 1.0000 60.0000 100.0000 0 0.2500
0 1.0000 1.0000 62.0000 100.0000 0.2500 0.2500
0 1.0000 1.0000 63.0000 100.0000 0.5000 0.2500
0 1.0000 1.0000 60.0000 100.0000 0 0.2500
0 1.0000 1.0000 62.0000 100.0000 0.2500 0.2500
0 1.0000 1.0000 63.0000 100.0000 0.5000 0.2500
0 1.0000 1.0000 60.0000 100.0000 0 0.2500
0 1.0000 1.0000 62.0000 100.0000 0.2500 0.2500
0 1.0000 1.0000 63.0000 100.0000 0.5000 0.2500
1.0000 1.0000 1.0000 58.0000 100.0000 0.7500 0.2500
1.0000 1.0000 1.0000 59.0000 100.0000 1.0000 0.2500
1.0000 1.0000 1.0000 65.0000 100.0000 1.2500 0.2500
1.0000 1.0000 1.0000 58.0000 100.0000 0.7500 0.2500
1.0000 1.0000 1.0000 59.0000 100.0000 1.0000 0.2500
1.0000 1.0000 1.0000 65.0000 100.0000 1.2500 0.2500
1.0000 1.0000 1.0000 58.0000 100.0000 0.7500 0.2500
1.0000 1.0000 1.0000 59.0000 100.0000 1.0000 0.2500
1.0000 1.0000 1.0000 65.0000 100.0000 1.2500 0.2500
1.0000 1.0000 1.0000 58.0000 100.0000 0.7500 0.2500
1.0000 1.0000 1.0000 59.0000 100.0000 1.0000 0.2500
1.0000 1.0000 1.0000 65.0000 100.0000 1.2500 0.2500
etc
Next I'd like column 1 to be replaced and to now have the pattern
[0 0 0 5 5 5 10 11 12 17 17 17 ]
which would then repeat (always from 5 integers later, until the end of the pattern so that the next 12 entries would be:
[22 22 22 27 27 27 32 33 34 39 39 39]
and so on.
It would be great if the code were relatively idiot-friendly (me-friendly) so
that I can easily manipulate this repeating pattern if need be. For example if z
were 4 rather than 3 then I would want the pattern
[0 0 0 0 5 5 5 5 10 11 12 13 18 18 18 18]
...Column 6 should then be replaced with a column that relates to column
1 in a (column_1 * 0.25) relationship.
i.e. for the above sample, where column 1 is:
[0 0 0 5 5 5 10 11 12 17 17 17 22 22 22 27 27 27 32 33 34 39 39 39]
column 6 would be:
[0 0 0 1.2500 1.2500 1.2500 2.5000 2.7500 3.0000 4.2500 4.2500 4.2500 5.5000
5.5000 5.5000 6.7500 6.7500 6.7500 8.0000 8.2500 8.5000 9.7500 9.7500
9.7500]
Can you help with that at all? Thanks very much in advance
TL;DR : For the final code : Go to section Full Code
The first part at least looks like a good job for reshape and repmat.
The tricky part is to not mess up with the dimensions.
Another approach will be to use cells and the function cellfun.
In this answer i will use a toy example defined as follow :
[~,ArrayIn]=meshgrid(1:7,1:20);
ArrayIn =
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
.....
z=3;
1. FIRST APPROACH : Use repmat and reshape :
Now, basically, the code will operate 3 major steps :
Step 1 : reshape the matrix so that it becomes a matrix of size size(ArrayIn,2)xzxsize(ArrayIn,1)/z
reshapedArrayIn=reshape(ArrayIn.',size(ArrayIn,2),z,[]);
Note that, after this step, the slices along the 3rd dimension are exactly the slices of length z that you want to repeat 3 times (only they are transposed, but it's needed because of the way reshape works).
reshapedArrayIn =
ans(:,:,1) =
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
ans(:,:,2) =
4 5 6
4 5 6
4 5 6
4 5 6
4 5 6
4 5 6
4 5 6
...
Also note that if the number of rows in your matrix is not dividable by z in the first place, the code will fail and you'll have to add extra lines before the call to reshape in order for it to work :
% Optional
if mod(size(ArrayIn,1),z)~=0
ArrayIn=[ArrayIn;zeros(z-mod(size(ArrayIn,1),z),size(ArrayIn,2))];
end
Step 2 : repeat the matrix 3 times along the second dimension
repArray=repmat(reshapedArrayIn,1,3,1);
Step 3 : reshape your matrix again in order to get a 2 dimensional matrix back, transpose the result to get it right
ArrayOut=reshape(repArray,size(ArrayIn,2),size(ArrayIn,1)*3).';
The result is as intended :
ArrayOut =
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
...
2. SECOND APPROACH : use cellfun
Another possibility to achieve this would be to convert you matrix to a cell and then use the function cellfun on all your subcells (This code would go after ArrayIn has been padded so that its number of rows is dividable by z:
Idy=7;
Idx=z*ones(size(ArrayIn,1)/z,1);
ArrayCell=mat2cell(ArrayIn,Idx,Idy);
CellOut=cellfun(#(A) repmat(A,3,1),ArrayCell,'UniformOutput',false);
ArrayOut=cell2mat(CellOut);
Giving also the expected result :
ArrayOut =
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
...
PART 2
For this part you can use what #tim gave you in the comments, although with a slight modification to take the length of your columns into account :
A = [zeros(1,z) 5*ones(1,z) 10:(9+z) 17*ones(1,z)];
m=ceil(size(ArrayOut,1)/(4*z));
UncutCol=repmat(A.',1,m)+repmat(22(*0:(m-1)),length(A),1);
Column1Out=UncutCol(1:size(ArrayOut,1));
Column6Out=Column1Out*0.25;
ArrayOut(:,1)=Column1Out;
ArrayOut(:,6)=Column6Out;
FULL CODE :
Approach 1 :
z=3;
[~,ArrayIn]=meshgrid(1:7,1:20);
if mod(size(ArrayIn,1),z)~=0
ArrayIn=[ArrayIn;zeros(z-mod(size(ArrayIn,1),z),size(ArrayIn,2))];
end
reshapedArrayIn=reshape(ArrayIn.',size(ArrayIn,2),z,[]);
repArray=repmat(reshapedArrayIn,1,3,1);
ArrayOut=reshape(repArray,size(ArrayIn,2),size(ArrayIn,1)*3).';
A = [zeros(1,z) 5*ones(1,z) 10:(9+z) 17*ones(1,z)];
m=ceil(size(ArrayOut,1)/(4*z));
UncutCol=repmat(A.',1,m)+repmat(22*(0:(m-1)),length(A),1);
Column1Out=UncutCol(1:size(ArrayOut,1));
Column6Out=Column1Out*0.25;
ArrayOut(:,1)=Column1Out;
ArrayOut(:,6)=Column6Out;
Approach 2 :
z=3;
[~,ArrayIn]=meshgrid(1:7,1:20);
if mod(size(ArrayIn,1),z)~=0
ArrayIn=[ArrayIn;zeros(z-mod(size(ArrayIn,1),z),size(ArrayIn,2))];
end
Idy=7;
Idx=z*ones(size(ArrayIn,1)/z,1);
ArrayCell=mat2cell(ArrayIn,Idx,Idy);
CellOut=cellfun(#(A) repmat(A,3,1),ArrayCell,'UniformOutput',false);
ArrayOut=cell2mat(CellOut);
A = [zeros(1,z) 5*ones(1,z) 10:(9+z) 17*ones(1,z)];
m=ceil(size(ArrayOut,1)/(4*z));
UncutCol=repmat(A.',1,m)+repmat(22*(0:(m-1)),length(A),1);
Column1Out=UncutCol(1:size(ArrayOut,1));
Column6Out=Column1Out*0.25;
ArrayOut(:,1)=Column1Out;
ArrayOut(:,6)=Column6Out;
Final Result :
ArrayOut =
0 1.0000 1.0000 1.0000 1.0000 0 1.0000
0 2.0000 2.0000 2.0000 2.0000 0 2.0000
0 3.0000 3.0000 3.0000 3.0000 0 3.0000
5.0000 1.0000 1.0000 1.0000 1.0000 1.2500 1.0000
5.0000 2.0000 2.0000 2.0000 2.0000 1.2500 2.0000
5.0000 3.0000 3.0000 3.0000 3.0000 1.2500 3.0000
10.0000 1.0000 1.0000 1.0000 1.0000 2.5000 1.0000
11.0000 2.0000 2.0000 2.0000 2.0000 2.7500 2.0000
12.0000 3.0000 3.0000 3.0000 3.0000 3.0000 3.0000
17.0000 4.0000 4.0000 4.0000 4.0000 4.2500 4.0000
17.0000 5.0000 5.0000 5.0000 5.0000 4.2500 5.0000
17.0000 6.0000 6.0000 6.0000 6.0000 4.2500 6.0000
22.0000 4.0000 4.0000 4.0000 4.0000 5.5000 4.0000
22.0000 5.0000 5.0000 5.0000 5.0000 5.5000 5.0000
22.0000 6.0000 6.0000 6.0000 6.0000 5.5000 6.0000
.....
I also want to provide a second solution, everything you need to know is provided as comments:
%%% INPUT DATA %%%
N = 3;
[~, A]=meshgrid(1:7,1:21);
numRows = size(A, 1);
if(mod(numRows, N) ~= 0)
% do padding here so that numRows can be devided by N, you can do it yourself :-)
end
%%% FIRST PART %%%
cnt = reshape(1:numRows,[N, numRows/N]) % create matrix which contains indices 1:numRows (number of Rows of A) in the desired manner
idx = repmat(cnt, N+1, 1) % number of copies of every line you want: N (so you'd have N+1 entries of every row (1 base and N copies))
A_cop = A(idx(:), :) % now idx(:) will give you the row-indices to replicate the rows of A in the desired manner
% --> 3-liner :-) could even be summed up in one single codeline :D
%%% SECOND PART %%%
c = [zeros(1,N) 5*ones(1,N) 10:(9+N) 17*ones(1,N)]; % base format
c2 = repmat(c', 1, ceil(size(A_cop, 1)/length(c))); % replicate it so that +i*22 can be added easily column-wise (i=column index)
c3 = bsxfun(#plus, c2, [(0:(size(c2,2)-1))]*22);
firstCol = c3(:); % linearize column-major memory
%%% THIRD PART -> merge both parts %%%
A_cop(:, 1) = firstCol(1:size(A_cop,1)); % set first column
A_cop(:, 6) = A_cop(:, 1)*0.25;
I think my first part might be a bit easier to understand then the solution from Bill, isnt it?
Im using indexing to copy rows within the input matrix A. That means, I generate a vector which contains the row-indices which I want to take from A, and this vector can contain values multiple times.
My example index-vector looks like this:
>> idx(:)
ans =
1
2
3
1
2
3
1
2
3
1
2
3
4
5
6
4
5
6
4
5
6
4
5
6
7
8
9
...
Using this, I make the final matrix A_cop and afterwards I apply the second part as described above in the comment --> replicate the base format c in a matrix and sum +i*22 in the i-th column, then linearizing the memory to yield one row-vector :-)

Adding data in intervals in Matlab

Hi I have data in MATLAB like this:
F =
1.0000 1.0000
2.0000 1.0000
3.0000 1.0000
3.1416 9.0000
4.0000 1.0000
5.0000 1.0000
6.0000 1.0000
6.2832 9.0000
7.0000 1.0000
8.0000 1.0000
9.0000 1.0000
9.4248 9.0000
10.0000 1.0000
I am looking for a way to sum the data in specific intervals. Example if I want my sampling interval to be 1, then the end result should be:
F =
1.0000 1.0000
2.0000 1.0000
3.0000 10.0000
4.0000 1.0000
5.0000 1.0000
6.0000 10.0000
7.0000 1.0000
8.0000 1.0000
9.0000 10.0000
10.0000 1.0000
i.e data is accumulated in the second column based on sampling the first row. Is there a function in MATLAB to do this?
Yes by combining histc() and accumarray():
F =[1.0000 1.0000;...
2.0000 1.0000;...
3.0000 1.0000;...
3.1416 9.0000;...
4.0000 1.0000;...
5.0000 1.0000;...
6.0000 1.0000;...
6.2832 9.0000;...
7.0000 1.0000;...
8.0000 1.0000;...
9.0000 1.0000;...
9.4248 9.0000;...
10.0000 1.0000];
range=1:0.5:10;
[~,bin]=histc(F(:,1),range);
result= [range.' accumarray(bin,F(:,2),[])]
If you run the code keep in mind that I changed the sampling interval (range) to 0.5.
This code works for all sampling intervals just define your wanted interval as range.
Yes and that's a job for accumarray:
Use the values in column 1 of F to sum (default behavior of accumarray) the elements in the 2nd column.
For a given interval of size s (Thanks to Luis Mendo for that):
S = accumarray(round(F(:,1)/s),F(:,2),[]); %// or you can use "floor" instead of "round".
S =
1
1
10
1
1
10
1
1
10
1
So constructing the output by concatenation:
NewF = [unique(round(F(:,1)/s)) S]
NewF =
1 1
2 1
3 10
4 1
5 1
6 10
7 1
8 1
9 10
10 1
Yay!!

Summing cumulative area under curves of overapping triangles

I have two matrices for several triangles:
x =
2.0000 5.0000 10.0000
8.0000 10.0000 12.0000
12.0000 24.0000 26.0000
22.0000 25.0000 28.0000
23.0000 26.0000 25.0000
23.5000 27.0000 27.5000
20.0000 23.0000 27.0000
21.0000 24.0000 27.0000
24.0000 25.0000 27.0000
24.0000 26.0000 27.0000
24.0000 28.0000 29.0000
19.0000 22.0000 25.0000
18.0000 21.0000 23.0000
y =
0 1.0000 0
0 0.8000 0
0 0.6000 0
0 0.8000 0
0 0.8000 0
0 0.8000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
one line is one triangle. Columns are x and y positions of each point of the triangles.
So, I plot all these triangles and I need to sum the cumulative area under the curve of the triangles.
I try to use the area function, but I couldn't find how to sum their areas.
EDIT: I need to plot the sum of the areas on a red line in the same graphics. So I don't want a number like 20 cm²... I would like something like that:
I suggest that you interpolate to create all your individual triangles and then add the results. First you will need to augment your x and y matrices with the beginning (the origin) and end points like so:
m = 30; %// This is your max point, maybe set it using max(x(:))?
X = [zeros(size(x,1),1), x, ones(size(x,1),1)*m];
Y = [zeros(size(y,1),1), y, zeros(size(y,1),1)];
then perform all the interpolations (I'll sum as I go):
xi = 0:0.1:m;
A = zeros(1,size(xi,2)); %// initialization
for row = 1:size(x,1)
A = A + interp1(X(row,:), Y(row,:), xi);
end
and finally plot:
plot(x,y,'k')
hold on
plot(xi,A,'r','linewidth',2)
using your example data this gives:

MatLab: Create 3D Histogram from sampled data

I have sampled data in the interval [0,1] in an Array transitions=zeros(101,101) which I want to plot as a 3D-histogram. transitions is filled with data similar to the example data provided at the end of this thread.
The first columns refers to the first observed variable X, the second column to the second variable Y and the third column is the normalized frequency. I.e. for the first row: the observed normalized frequency of the variable pair (0,0) is 0.9459. The sum of the normalized frequencies for (0,Y)thus is 1.
I tried to make (sort of) a 3D histogram with the following code:
x_c = (transitions(:,1) * 100)+1;
y = (transitions(:,2) * 100)+1;
z = transitions(:,4);
%A = zeros(10,10);
A = zeros(max(x_c),max(y));
for i = 1:length(x_c)
try
if(z(i)>0)
A(int32(x_c(i)), int32(y(i))) = abs(log(z(i)));
else
% deal with exceptions regarding log(0)
A(int32(x_c(i)), int32(y(i))) = 0;
end
catch
disp('');
end
end
bar3(A);
However, since it is sampled data in a discrete space A the output looks like the plot below. This is somehow misleading as there are 'gaps' in the plot (z-value = 0 for coordinates where I have no sampled data). I rather would like to have the sampled data being assigned to their corresponding plots, thus resulting in a 'real' 3d histogram.
By the way, as a result of my 'hack' of creating A also the x-,y- and z-scale is not correct. The 3D histogram's axes (all three) should be in the interval of [0,1].
ans =
0 0 0.9459
0 0.0500 0.0256
0 0.1000 0.0098
0 0.1100 0.0004
0 0.1500 0.0055
0 0.1600 0.0002
0 0.2000 0.0034
0 0.2100 0.0001
0 0.2500 0.0024
0 0.2600 0.0001
0 0.3000 0.0018
0 0.3200 0.0000
0 0.3700 0.0000
0 0.4000 0.0010
0 0.4200 0.0000
0 0.4500 0.0007
0 0.5000 0.0007
0 0.5300 0.0000
0 0.5500 0.0005
0 0.6000 0.0005
0 0.6300 0.0000
0 0.7000 0.0002
0 0.7400 0
0 0.7500 0.0003
0 0.7900 0.0000
0 0.8000 0.0002
0 0.8400 0.0000
0 0.8500 0.0002
0 0.8900 0.0000
0 0.9000 0.0002
0 0.9500 0.0001
0 1.0000 0.0001
0.0500 0 0.0235
0.0500 0.0500 0.0086
0.0500 0.1000 0.0045
. . .
. . .
. . .
. . .
. . .
0.9500 0.9000 0.0035
0.9500 0.9500 0.0066
0.9500 1.0000 0.0180
1.0000 0 0.0001
1.0000 0.0500 0.0001
1.0000 0.1000 0.0001
1.0000 0.1100 0.0000
1.0000 0.1500 0.0001
1.0000 0.1600 0.0000
1.0000 0.2000 0.0001
1.0000 0.2100 0.0000
1.0000 0.2500 0.0001
1.0000 0.2600 0.0000
1.0000 0.3000 0.0001
1.0000 0.3200 0.0000
1.0000 0.3700 0.0000
1.0000 0.4000 0.0002
1.0000 0.4200 0
1.0000 0.4500 0.0002
1.0000 0.5000 0.0003
1.0000 0.5300 0.0000
1.0000 0.5500 0.0004
1.0000 0.6000 0.0004
1.0000 0.6300 0.0000
1.0000 0.7000 0.0007
1.0000 0.7400 0.0000
1.0000 0.7500 0.0010
1.0000 0.7900 0.0000
1.0000 0.8000 0.0015
1.0000 0.8400 0.0001
1.0000 0.8500 0.0024
1.0000 0.8900 0.0002
1.0000 0.9000 0.0042
1.0000 0.9500 0.0111
1.0000 1.0000 0.3998
I found a solution by working on the non-aggregated data. In particular each row of the data set transitions contains one observation of Xand Y. I used the code below to produce a normalized 3D histogram (and a 2D map) as folllows:
function createHistogram(transitions)
uniqueValues = unique(transitions(:,1));
biases = cell(numel(uniqueValues),1);
for i = 1:numel(uniqueValues)
start = min(find(transitions(:,1) == uniqueValues(i)));
stop = max(find(transitions(:,1) == uniqueValues(i)));
biases(i) = mat2cell(transitions(start:stop,2));
end
combinedBiases = padcat(biases{1},biases{2},biases{3},biases{4},...
biases{5},biases{6},biases{7},biases{8},biases{9},biases{10},...
biases{11},biases{12},biases{13},biases{14},biases{15},biases{16},...
biases{17},biases{18},biases{19});
bins = 0:0.1:1;
[f, x] = hist(combinedBiases, bins);
%
% normalize
%
for i = 1:numel(f(1,:))
for j = 1:numel(f(:,i))
f(j,i) = f(j,i)/numel(biases{i});
end
end
bHandle = bar3(x, f);
ylim([-0.04,1.04])
for k = 1:length(bHandle)
zdata = get(bHandle(k),'ZData');
set(bHandle(k),'CData',zdata, 'FaceColor','interp');
end
colormap('autumn');
hcol = colorbar();
axis('square');
cpos=get(hcol,'Position');
cpos(4)=cpos(4)/3; % Halve the thickness
cpos(2)=0.4; % Move it down outside the plot#
cpos(1)=0.82;
set(hcol, 'Position',cpos);
xlabel('Enrollment biases');
ylabel('Aging biases');
zlabel('Bias transition probability');
title(strcat('Probability mass function of bias transitions (', device,')'));
set(gca,'XTick',0:2:20);
set(gca,'XTickLabel',0:0.1:1);
print('-dpng','-r600',strcat('tau_PMF3D_enrollment-ageing-', device));
view(2);
cpos(1)=0.84;
set(hcol, 'Position',cpos);
print('-dpng','-r600',strcat('tau_PMF2D_enrollment-ageing-', device));
end
From the comment on the question it appears you have the values you want to represent each bin count. If so an alternative solution is to plot using hist3 with "junk" data using correct x and y scales and then update the zdata of the surface object created with your bin data (modified to be in the correct format).
This modification to the bin data is fairly simple and consists of reshaping into a matrix then replicating and padding all the elements, the method is included in the code below.
Based on the ans variable at the end of the question, assuming
ans(:,1) gives x values
ans(:,2) gives y values
ans(:,3) gives the normalised bin counts
code
%// Inputs
zdata=ans(:,3); %// zdata=rand(21*21,1); % for testing
xvalues = 0:0.05:1;
yvalues = 0:0.05:1;
%// plot with junk data, [0,0] in this case
nx = numel(xvalues); ny = numel(yvalues);
bincenters = { xvalues , yvalues };
hist3([0,0],bincenters);
Hsurface = get(gca,'children');
%// apply bin count format
pad = [0 0 0 0 0;0 1 1 0 0;0 1 1 0 0;0 0 0 0 0;0 0 0 0 0]; %// padding for each point
ztrans=kron(reshape(zdata,[nx,ny]),pad); %// apply padding to each point
%// update plot
set(Hsurface,'ZData',ztrans)
%// to set colour based on bar height
colormap('autumn');
set(Hsurface,'CData',ztrans,'FaceColor','interp')
output

matlab: duplicate rows removal [duplicate]

This question already has answers here:
matlab: remove duplicate values
(3 answers)
Closed 9 years ago.
I had a question and got an answer yesterday about removing doubling rows in a matrix, and I can't figure out why it omits certain rows in a matrix.
With a matrix:
tmp2 =
0 1.0000
0.1000 1.0000
0.2000 1.0000
0.3000 1.0000
0.3000 2.0000
0.4000 2.0000
0.5000 2.0000
0.6000 2.0000
0.7000 2.0000
0.7000 3.0000
0.8000 3.0000
0.9000 3.0000
1.0000 3.0000
1.1000 3.0000
1.2000 3.0000
I need to remove the rows:
0.3000 2.0000
0.7000 3.0000
I tried to do it with
[~,b] = unique(tmp2(:,1));
tmp2(b,:)
I wrote something on my own
tmp3 = [];
for i=1:numel(tmp2(:,1))-1
if tmp2(i,1) == tmp3
tmp2(i,:) = [];
end
tmp3 = tmp2(i,1);
end
But all of the methods seem to omit the first row to remove... Please help, as I already spent some hours trying to fix it myself (I suck at programming...) and nothings seems to work. The matrix is an example, but generally if two rows have the same value in the first column I have to remove the second one
You were on the right track...
tmp2 = [...
0 1
1 1
2 3
2 5
3 5
4 7
5 4
5 8
6 1
];
Now call unique like you did, but use the flag first to grab the first unique:
[~,li]=unique(tmp2(:,1),'first');
tmp_unique = tmp2(li,:);