Plotting a normpdf in 3D over scatter plot/linear regression - matlab

I have a set of data x(1000,2),
2 18.1199158925616
3 9.56472607516328
7 34.3629828698699
4 30.9865760010538
7 54.4869549747429
8 54.7696742935546
2 1.45832407805944
3 15.4231700658276
8 57.0479651194063
1 5.34909555648445
2 11.5593766410445
2 17.4392978010484
6 25.4072607558367
4 15.1248062077068
2 13.2035176450795
7 33.2507069131440
5 21.6859046133920
3 18.4458236149053
1 0.824962982951128
8 46.6322862041701
8 43.6889420657037
2 17.0930689315346
3 13.9754117410459
2 1.99260423380962
11 86.3172411757665
8 50.6244869641866
1 1.16602336459361
2 12.6604166373800
2 17.4519078987572
5 27.4799515521804
which I have plotted plot(x(:,1),x(:,2),'*r');in scatter form:
but would like to have something like below using normpdf for selected values of x(:,1):
To find values in x(:,2) column corresponding to x(:,1)==3:
[x3]=x(find(x(:,1)==3),2);
mu=mean(x3);
sig=std(x3);
Y=normpdf(x3,mu,sig);
figure('color',[1,1,1]);
hhh=plot3(3*ones(length(xi)),x(find(x(:,1)==3),2),Y,'-r')
p = polyfit(x(:,1),x(:,2),1);
plin=plot(x(:,1),polyval(p,x(:,1)),'-b');
but how do I get the red dotted pdf to be a smooth curve as '-r' gives me zig-zag lines. Do I have to order the data in some way?
Also how do I get the red dots in the center of the normal curve down to the blue line?
And perhaps most importantly, as a well informed reader would you like to see this type of plot or perhaps something else less fancy?

Yes, a sorting of the x-values should get you the red curve. Also you do not need find() here. I have not tested the code, but these changes should work:
[x3]=sort(x(x(:,1)==3,2));
mu=mean(x3);
sig=std(x3);
Y=normpdf(x3,mu,sig);
figure('color',[1,1,1]);
hhh=plot3(3*ones(length(xi)),x3,Y,'-r')
p = polyfit(x(:,1),x(:,2),1);
plin=plot(x(:,1),polyval(p,x(:,1)),'-b');
As for the value of such a plot, I would guess that it will be quite cluttered. But I guess it could be used to give a general view of the distribution of the data.

Related

Vectorizing cell find and summing in Matlab

Would someone please show me how I can go about changing this code from an iterated to a vectorized implementation to speed up performance in Matlab? It takes approximately 8 seconds per i for i=1:20 on my machine currently.
classEachWordCount = zeros(nwords_train, nClasses);
for i=1:nClasses % (20 classes)
for j=1:nwords_train % (53975 words)
classEachWordCount(j,i) = sum(groupedXtrain{i}(groupedXtrain{i}(:,2)==j,3));
end
end
If context is helpful basically groupedXtrain is a cell of 20 matrices which represent different classes, where each class matrix has 3 columns: document#,word#,wordcount, and unequal numbers of rows (tens of thousands). I'm trying to figure out the count total of each word, for each class. So classEachWordCount should be a matrix of size 53975x20 where each row represents a different word and each column a different label. There's got to be a built-in function to assist in something like this, right?
for example groupedXtrain{1} might start off like:
doc#,word#,wordcount
1 1 3
1 2 1
1 4 3
1 5 1
1 8 2
2 2 1
2 5 4
2 6 2
As is mentioned in the comments, you can use accumarray to sum up the values in the third column for each unique value in the second column for each class
results = zeros(nwords_train, numel(groupedXtrain));
for k = 1:numel(groupedXtrain)
results(:,k) = accumarray(groupedXtrain{k}(:,2), groupedXtrain{k}(:,3), ...
[nwords_train 1], #sum);
end

How to do a "even" extension of a plot in Matlab/Octave

clc
clear all
z=[1 2 3 4 5];
d=[10 20 30 40 50];
plot(d,z)
z=[z fliplr(z)];
z(5)=[];
d=[d fliplr(d)];
d(5)=[];
figure(2)
plot(d,z)
z=[1 2 3 4 5];
z=[z 6 7 8 9];
figure(3)
plot(d,z)
I'm trying to "flip a graph on itself" or "fold it" , the first figure does this "/" the second one ALSO does "/" but it goes forward and then backwards, the third one does ">" and i need it to do "/\"or "^" whatever you think depicts it better, basically repeat the somewhat transpose of a graph, i need a mirror in front of it, something like doing even extensions in Fourier series i believe?
The problem is more complex than this, but this step is vital to keep doing it, please help me do so :/, i AM using Octave, but for something as basic as this MATLAB and Octave codes should be interchangeable.Thanks in advance
Even extension means f(-x) = f(x): same z-value when the argument d changes sign. The process you describe is not exactly that, since the reflected part is to be added at the end of original plot, to make /\ shape out of / shape. This is how it can be done:
ze = [z z(end-1:-1:1)]
de = [d 2*d(end)-d(end-1:-1:1)]
plot(de, ze)
The z-value are just reflected (repeated from end-1 to 1, in reverse order); the d-values are transformed by the map that sends x to 2*d(end) - x. This is a reflection that keeps d(end) fixed.
In your example, ze is [1 2 3 4 5 4 3 2 1] and
de is [10 20 30 40 50 60 70 80 90].

Matlab complex matrix magnitude

I have a matrix S something like:
1 4 7
2 5 8
3 6 9
Then I make a=complex(S{2},S{3}) and wanted to find the abs(a);. This is not possible in MATLAB as a is not an integer - it is a matrix. How can I get the magnitude of each row of matrix a?
PS: the matrix is read from a text file using textscan() as S = textscan(fileID,'%d %d %d', 'delimiter','\t');.
Second question:
Assuming again hav the following S matrix.
1 4 7 2 1
2 5 8 3 4
3 6 9 6 8
Now I wanted to arrange them in such way that column 2,3 and 4,5 alternate like this:
4 2
7 1
5 3
8 4
6 6
9 8
How can I do that without using a loop?
Thanks.
Going with my assumption in the comments, I'm going to assume that the second column consists of your real component of your matrix while the third column consists of your imaginary components. Your matrix S is actually a cell array of elements. You don't need to use complex then abs. You can simply take each of the columns, individually square them, add them together and take the square root. What I would do is convert the cell array into a 2D matrix, cast it to double to allow for floating point precision when finding the magnitude, and do what I just did above. This is necessary because abs and sqrt will only work for floating-point numbers. Your elements in S are already int32 due to the %d delimiter from textread. In other words:
Smat = double(cell2mat(S));
realComp = Smat(:,2);
imagComp = Smat(:,3);
mag = sqrt(realComp.^2 + imagComp.^2);
mag will thus return the magnitude of each row for you, assuming that the second column is the real component and the third component is the imaginary component as we specified.
However, if you're dead set on using complex and abs, you can do it like so:
Smat = double(cell2mat(S));
imagNumbers = complex(Smat(:,2), Smat(:,3));
mag = abs(imagNumbers);
This should still give you the same results as we talked about above.
Edit
Seeing your edit in your post above, we can achieve that quite easily by subsetting the matrix, then applying reshape to each part of the matrix you want. In other words:
Smat = double(cell2mat(S));
realMat = Smat(:,2:3); %// Grab second and third columns
imagMat = Smat(:,4:5); %// Grab fourth and fifth columns
realCol = reshape(realMat.', [], 1); % // Form the columns like you specified
imagCol = reshape(imagMat.', [], 1);
finalMatrix = [realCol imagCol];
finalMatrix should contain those two columns that you specified above in a single matrix.

How to add label or change the colour of certain bar in multiple bar plot

Lets say I have a multiple bar, which looks smth like that:
aa = repmat([1 2 10 5 15 3], 5,1)
aa =
1 2 10 5 15 3
1 2 10 5 15 3
1 2 10 5 15 3
1 2 10 5 15 3
1 2 10 5 15 3
bar(aa)
What I need is to put a star or a label on some certain column, which sutisfies some conditions. Another option is to change the colour of that bar.
If I could get the coordinates of each column I could use plot. Or maybe I can modify errorbar somehow?
Thanks for any advices.
Problem
You can get the x and y values of the bars (x=horizontal position, y=height of each bar) using:
hb=bar(aa);
x=cell2mat(get(hb,'Xdata'));
y=cell2mat(get(hb,'Ydata'));
which you can then use to plot a textlabel with text,
or even just plot the mark symbols with plot:
plot(x,y,'*',Markersize',12)
Unfortunately, this only works correctly if you only have one single serie of data, because Xdata contains the index in the series (1,2,3,etc). For multiple series matlab spreads the bars around that index, but the Xdata values are all the same (despite in the plot, they aren't plotted at exact the same position).
Solution
Add the option 'hist' to the bar plotting:
hb=bar(aa,'hist')
this creates patches rather than barseries, and
x=cell2mat(get(hb,'Xdata'));
y=cell2mat(get(hb,'Ydata'));
now contains the (actual) corners of those patches. Extract the x-center as follows:
xcenter = 0.5*(x(2:4:end,:)+x(3:4:end,:));
The height is obtainable with one of the upper corners of the patch:
ytop = y(2:4:end,:);
Now you can use that for the plotting:
idx_mark = 3;
plot(xcenter(idx_mark ,:),ytop(idx_mark ,:),'*','Markersize',12)
or for annotation:
text(xcenter(idx_mark ,2),ytop(idx_mark ,2),'MARKED',...
'HorizontalAlignment','center', ...
'VerticalAlignment','bottom' )
I think that what you could do that (for the colors) with playing a little with the bar function properties.
It also all depends if you know more or less how your plot will look like; if you know beforehand I think you could use XTick and XTicklabel to label you columns.
http://www.mathworks.nl/help/techdoc/ref/bar.html

how to plot with vectical lines with gnuplot?

I study for sometime but didn't get the answer yet.
The data is like:
#X0, Y0_0, Y0_1
1 1 2
3 2 4
7 1 3
....
I need to draw vectical line from (X0, Y0_0) to (X0, Y0_1). gnuplot has financebar and candlesticks but they are too much.
I just want a single vectical line for each record.
Appreciate for any help.
If I understand correctly what you are after, the following script should do the job:
set offsets 1, 1, 1, 1
set key off
plot "-" u 1:2:(0):($3) w vectors nohead
1 1 2
3 2 4
7 1 3
e
What it does:
It sets the offset, so that you can see the left and right vector, so that it is not hidden by the axis.
Remove the label, since it has no use in this example
Plots vectors with no head (a single vertical line). The "parameters" are as stated here the x y dx dy. The (0) stands for dx=0 and the brackets are important. Otherwise the column 0 would be used which in gnuplot is the index of the data (line number).
Below the plot you will get with the script above: