I have many data need to be plotted as waterfall in matlab. I have more than 10 columns of data, each column represents one data data set. I put all data in a big matrix such that the first data set put in the first row of matrix, the second data set will be in the second row ... etc. After all those data stored in a matrix, I use the waterfall to plot those data. For each column, it contains about 10,000 data points which corresponds to x variable ranged from -5 to 5. But in the waterfall, it shows 0 to 10, 000 instead of -5 to 5 in the x axis. How do I force matlab to show the correct range? thx
mydata = zeros(13, 10000);
mydata(1, :) = ... ; % first data set
mydata(2, :) = ... ; % second data set
...
mydata(13, :) = ... ; % last data set
waterfall(mydata)
If you look at the documentation for waterfall (you can do this easily by placing the cursor in the command in your editor and hitting F1), you will see that you can invoke the waterfall command with different syntax . .
% Syntax
waterfall(Z)
waterfall(X,Y,Z)
waterfall(...,C)
waterfall(axes_handles,...)
h = waterfall(...)
Rather than just call the waterfall plot with the data Z, supply it with the X and Y range data also. For example . . .
mydata = rand(13, 10000);
Y = 1:size(mydata,1);
X = linspace(-5, 5,size(mydata,2));
waterfall(X, Y , mydata)
Related
I have a 144x91x92 matrix stored in o3{1}. I'd like to look across the third dimension (representing the days in one season) and sort it. Then, I want to pull out the top 10 and bottom 10 percentile of values including the index of those values. This would find the top 10 and bottom 10 percentile of days for each grid cell (this would be different for each grid cell).
I'm trying the following:
[Y,I] = sort(o3{1},3); % sort o3 along 3rd dimension
o3_sorted = o3{1}(I);
ind_top10 = o3_sorted(90);
ind_bot10 = o3_sorted(10);
But I know I'm not pulling out the top 10 and bottom 10th percentile correct. Plus, this way does not tell me the indices (different for each of the 144x91 grid cells) for the top and bottom 10 percentile of days. I am hoping to end up with 144x91x10 matrices for the top 10 percentile of days, the bottom 10 percentile of days, and the indices for each.
Try it like this:
[~, I] = sort(o3{1},3); %// sort o3 along 3rd dimension
ind_top10 = I(:,:,end-8:end);
ind_bot10 = I(:,:,1:9);
I3 = cat(3, ind_top10, ind_bot10); %// you might want to skip this but and just work with the top and bottom separately from here on
[I1, I2, ~] = ndgrid(1:size(o3{1},1), 1:size(o3{1},2), 1:size(I3,3));
ind = sub2ind(size(o3{1}),I1,I2,I3)
And now
o3{2}(ind)
o3{3}(ind)
%// etc...
Here's a slightly different idea from what Dan had suggested:
%% // Init
clear variables; clc;
%% // Generate some data:
o3 = cell(3,1);
for indO = 1:3
o3{indO} = randi(intmax('uint16'),144,91,92,'uint16');
end
%% // Find 10 & 90 percentiles:
percentiles = cat(3,prctile(o3{1},10,3),prctile(o3{1},90,3));
%% // Find indices of relevant values
select_bot10 = bsxfun(#ge,o3{1},percentiles(:,:,1)); %// replace #ge with #gt if needed
select_top10 = bsxfun(#le,o3{1},percentiles(:,:,2)); %// replace #le with #lt if needed
%// Another optional way to index the values if required:
[rb,cb,vb] = ind2sub(size(select_bot10),find(select_bot10));
[rt,ct,vt] = ind2sub(size(select_top10),find(select_top10));
%% // Get values from o3{1..3} etc.
bot10 = o3{1}(select_bot10);
top10 = o3{1}(select_top10);
%// etc.
This solution might not be suitable for your specific needs as it is, but adaptations should be straightforward. Also note that since exact percentiles are taken, the number of elements would probably differ between bot10 and top10.
Credit for the 3D find goes to Kenneth Eaton / gnovice.
There is a Matrix of 500000000 X 5.
And the sample of this data is like this :
1 01 06:0 48407
1 01 06:1 48407
.
.
.
865850 31 23:5 1586884493
Each column means [area_number date hour:minute amount_of_data]
I want to load them entirely, after that make another 865850 X 4464 matrix from their 5th column values. In this new matrix, row insists area_number. And each column means amout_of_data according to time priority.
This is what I wrote.
clear all; close all;
fileID=fopen('data2.txt','r');
Data=fscanf(fileID, '%d %d %d:%d %d',[5 100000]);
Data = Data';
Zeros = zeros(4000, 4464);
DataA = Data(:,1); % indexs
DataB = Data(:,2); % dates
DataC = Data(:,3); % hours
DataD = Data(:,4); % minutes
DataE = Data(:,5); % data
for m=1:40000
r = DataA(m);
c = (DataB(m)-1)*24*6 + DataC(m)*6 + DataD(m);
Zeros(r,c) = DataE(m);
end
I can't finish it because the matrix too big to load it at once.
It overs memory limitation of MATLAB.
Please help me...
Thank you~!
To solve your problem, using the matfile command is probably the best choice. It allows you to write data directly to a mat-file on the filesystem but access it like a variable.
If I understood your data right, all lines with the same index are next to each other, and all data with the same index is small enough to fit your memory.
Read all data with index 1
process it like you did above, creating one row of your intended matrix
Write this row to your matfile
Proceed with the next index until you reach the end
I want to find the local maximum and the minimum values between this 2 local maximums in every column of the image img_gauss. And then put them minimum values at 1 (white). Anyone knows how to do this in a easy way?
Below I have my code. But I'm having some trouble, I try in every iteration (for each column) take the localization (locs) and then put them in the array peaks_column, to have the peaks localization by column, but this error apears:
Subscripted assignment dimension mismatch.
Error in cropping_image_long (line 136)
peaks_column(1:size(Intens_graph,1),x)=pks(:,1);
pks= [];
locs_column=zeros(20,size(img_gauss,2));
locs= [];
pks_column=zeros(20,size(img_gauss,2));
for x = 1:size(img_gauss,2) % 2 = colunas x(colunas)
% make a row wise intensity distribution graphic for each column
Intens_graph(:,x)=img_gauss(size(img_gauss,1):-1:1,x);
[pks,locs] = findpeaks(Intens_graph(:,x));%find the local maximum
peaks_column(1:size(Intens_graph,1),x)=pks(:,1); %associate to each column
locs_column(1:size(Intens_graph,1),x)=locs(:,1);
BW = imregionalmin(Intens_graph);
end
Not exactly sure what you mean with the minimums. Between two maximas there will always be one minimum. So i will find minimas with findpeaks.
% test data
data = rand(100);
% for saving minima and maxima positions
minimas = zeros(size(data));
for i = 1:size(data,2)
column = data(:,i);
[~,minis] = findpeaks(-column);
% save the positions
minimas(sub2ind(size(minimas),minis,repmat(i,length(minis),1))) = 1;
end
%generate result, paint all minimas with 1
result = data;
result(minimas==1) = 1;
Okay so this sounds easy but no matter how many times I have tried I still cannot get it to plot correctly. I need only 3 lines on the same graph however still have an issue with it.
iO = 2.0e-6;
k = 1.38e-23;
q = 1.602e-19;
for temp_f = [75 100 125]
T = ((5/9)*temp_f-32)+273.15;
vd = -1.0:0.01:0.6;
Id = iO*(exp((q*vd)/(k*T))-1);
plot(vd,Id,'r',vd,Id,'y',vd,Id,'g');
legend('amps at 75 F', 'amps at 100 F','amps at 125 F');
end;
ylabel('Amps');
xlabel('Volts');
title('Current through diode');
Now I know the plot function that is currently in their isn't working and that some kind of variable needs setup like (vd,Id1,'r',vd,Id2,'y',vd,Id3,'g'); however I really can't grasp the concept of changing it and am seeking help.
You can use the "hold on" function to make it so each plot command plots on the same window as the last.
It would be better to skip the for loop and just do this all in one step though.
iO = 2.0e-6;
k = 1.38e-23;
q = 1.602e-19;
temp_f = [75 100 125];
T = ((5/9)*temp_f-32)+273.15;
vd = -1.0:0.01:0.6;
% Convert this 1xlength(vd) vector to a 3xlength(vd) vector by copying it down two rows.
vd = repmat(vd,3,1);
% Convert this 1x3 array to a 3x1 array.
T=T';
% and then copy it accross to length(vd) so each row is all the same value from the original T
T=repmat(T,1,length(vd));
%Now we can calculate Id all at once.
Id = iO*(exp((q*vd)./(k*T))-1);
%Then plot each row of the Id matrix as a seperate line. Id(1,:) means 1st row, all columns.
plot(vd,Id(1,:),'r',vd,Id(2,:),'y',vd,Id(3,:),'g');
ylabel('Amps');
xlabel('Volts');
title('Current through diode');
And that should get what you want.
I want to show the p value that was used to generate each curve next to each of the curves plotted. Note that since there is a plot of E and -E, the same p value should be next to both. I've been attempting this for a while and I have not come across anything super useful.
t = -3.1;%coupling
a = 1;%distance between r1 and r3
n = 5;%latice vector span in a1 direction
m = 1;%latice vector span in a2 direction
i = -7;%unique axial vector t_hat direction
j = 11;%unique axial vector c_hat direction
max_p = abs((n*(i+j/2)-j*(m+n/2)));%# of unique p values
La = sqrt(3)*sqrt(m^2+n*m+n^2)*a/gcd(2*n+m,2*m+n);%unit cell length
C = sqrt(n^2+n*m+m^2);%circumference of the nanotube
hold on;
for p=0:1:max_p
kt = -pi/La:.05:pi/La;
kc = 2*pi*p/C;
ka1 = kc*a*.5*(2*n+m)/C + kt*a*sqrt(3)*.5*m/C;
ka2 = kc*a*.5*(n+2*m)/C - kt*a*sqrt(3)*.5*n/C;
E = abs(t+t*exp(1i*ka2)+t*exp(1i*ka1));
title_ = sprintf('(%d,%d) Carbon Nanotube Dispersion Diagram',n,m);
title(title_);
xlabel('k_{t}a');
ylabel('Energy (eV)');
plot(kt,E);
plot(kt,-E);
end
There is a command named text that writes comments into the figures,
http://www.mathworks.se/help/techdoc/ref/text.html
with if you can't solve it with that and the to string operation i misunderstood the question
First, do you need to plot both E and -E? Since these are the same except for their sign you don't really add any information to the plot by having -E there as well. However, if you do need both lines, then just construct an array of strings for the legend, during the loop, which has each string included twice (once for E and once for -E).
... Initial calculations ...
hold on;
for p=0:1:max_p
kt = -pi/La:.05:pi/La;
kc = 2*pi*p/C;
ka1 = kc*a*.5*(2*n+m)/C + kt*a*sqrt(3)*.5*m/C;
ka2 = kc*a*.5*(n+2*m)/C - kt*a*sqrt(3)*.5*n/C;
E = abs(t+t*exp(1i*ka2)+t*exp(1i*ka1));
plot(kt,E);
plot(kt,-E);
% Construct array containing legend text
legend_text{2*(p+1)-1} = strcat('p=', num2str(p));
legend_text{2*(p+1)} = strcat('p=', num2str(p));
end
title_ = sprintf('(%d,%d) Carbon Nanotube Dispersion Diagram',n,m);
title(title_);
xlabel('k_{t}a');
ylabel('Energy (eV)');
legend(legend_text)
I am sure there is a more elegant way of constructing the legend text, but the above code works. Also, notice that I moved the calls to xlabel, ylabel and title to outside of the loop. This way they are only called once and not for each iteration of the loop.
Finally, you need to take care to ensure that each iteration of the loop plots with a different line colour or line style (see edit below). You could colour/style each pair of E and -E lines the same for a given iteration of the loop and just display the legend for E (or -E), which would obviously halve the number of legend entries. To do this you will need to hide one of line's handle visibility - this prevents it from getting an item in the legend. To do this use the following in your loop:
plot(kt, E);
plot(kt,-E, 'HandleVisibility', 'off');
% Construct array containing legend text
legend_text{p+1} = strcat('p=', num2str(p));
Finally, it is best to include clear all at the top of your Matlab scripts.
Edit: To have each plotted line use a different colour for each iteration of your loop use something like the following
... initial calculations ...
cmap = hsv(max_p); % Create a max_p-by-3 set of colors from the HSV colormap
hold on;
for p = 0:1:max_p
plot(kt, E, 'Color', cmap(p,:)); % Plot each pair of lines with a different color
plot(kt, -E, 'Color', cmap(p,:));
end