How to plot a multidimensional array in matlab? - matlab

I have a table as follows
system:index 2017_06_18 2017_06_19 2017_06_20 2017_06_21
2 612.8099664 1174.656713 1282.083251 815.3828357
3 766.4103726 1345.135952 1322.726083 749.998993
4 765.0230453 1411.669136 1350.437586 610.9541838
5 553.5858458 1374.14789 1152.086957 566.7924468
6 466.9780908 1311.903756 1060.494001 559.1982264
7 257.1162602 1270.182385 988.5455285 562.9224932
8 230.6611542 1310.971988 1001.548768 502.3266959
I want to plot a 2d-colormap representing system:index as y axis, dates as x axis and values under dates as colors. I tried with the following code but it did not give what I want.
clear
clc
filename = 'TurbidityDailyMean.xlsx';
data = xlsread(filename,'TurbidityDailyMean','A1:E8');
figure;
hold on
for i = 2:5
y = data(:,1);
x = data(:,i);
plot(x,y)
end
I need to map a colormap as mentioned above. But from what I tried it gives something else. And another fact is that I can't insert system:index and dates row into matlab with relevant data.

Thanks to my supervisor Dr.Kavinda,enter image description here the solution I adopted from him was as follows
data1 = csvread('TurbidityDailyMean.csv',1,1);
[mm,nn]=size(data1)
xx=ones(mm,nn);
yy=ones(mm,nn);
for j=1:nn
xx(:,j)=j;
end
for i=1:mm
yy(i,:)=i;
end
zz=data1;
h1=pcolor(xx,yy,zz);
shading flat
set(gcf,'color',[1,1,1])
axis([1 5 1 7]);
jet2=jet;
jet2(1,:)=1.0;
colormap(jet2)
caxis([0.0 0.13])
hold on
xlabel('Julian Day');
ylabel('y (?~1 km)');
colorb=colorbar;
set(get(colorb,'ylabel'),'String','Normalized Red Band Reflectance','fontsize',15,
'color', 'k');
set(get(colorb,'xlabel'),'fontsize',20, 'color', 'k');
grid on

Related

Plot categorical x axis

I have a data set (shown in picture from excel):
and I want to make a scatter plot with the categories along the x-axis:
My current code is:
Mydata= readtable('D:\Download\Book1.xlsv');
y= Mydata.Group1;
x=Mydata.Y;
size= 50;
scatter (x,y,size,'magenta','filled','square');
hold on
y= Mydata.Group2;
scatter(x,y,size,'red','filled','d');
y= Mydata.Group3;
scatter(x,y,size,'b','filled','p');
y= Mydata.Group4;
scatter(x,y,size,'yellow','filled','h');
y=Mydata.Group5;
scatter(x,y,size,'k','filled','o');
hold off
With this current code, all data were plotted in one line not like in the picture. I also want to add an error bar for each data later. How can I achieve this?
Here is one way to plot data points for a category and color them by series.
% generate numbers
X = rand(3,4);
cols = {'r','b','g'}
num_categories = size(X)(2);
num_series = size(X)(1);
labels = cell(num_categories,1)
legends = cell(num_series,1)
figure;
hold on;
% plot series
for i=1:num_series
scatter(1:num_categories,X(i,:),cols{i})
legends{i,1} = ['series ', num2str(i)];
end
% generate labels for categories
for i=1:num_categories
labels{i,1} = ['category ', num2str(i)];
end
set(gca, 'xtick',1:num_categories)
set(gca, 'xticklabel', labels)
axis([0, num_categories+1, 0, 1]);
legend(legends)
Can you elaborate what you mean with error bars and where you would want them to be? Do you want errors per category and series?

How to detect peaks on gray background with Matlab FastPeakFind?

I am testing the validity of the FileExchange project FindPeaksFast with different linewidths and backgrounds.
Test 1 is successful and the tool detects all peaks from 1px to 10 px.
However, Test 2 fails when testing to find peaks on the frame of an object plot i.e. an object (plot) on gray background.
The tool works well on white background.
Code
close all; clear all; clc;
f = figure;
hax = axes(f);
% Comment this out for Test 2
%zeroFigureDecorations(hax);
af = figure('Name', 'Do Not Touch');
x = rand(1,100);
y = rand(1,100);
linewidth=1;
plot(hax, x,y, 'LineWidth', linewidth);
I = getframe(hax);
I = I.cdata;
% https://se.mathworks.com/matlabcentral/fileexchange/37388-fast-2d-peak-finder
p=FastPeakFind(I);
% Input: 344x435x3 uint8
hold(hax, 'on');
plot(hax, p(1:2:end),p(2:2:end),'r+')
hold(hax, 'off');
function zeroFigureDecorations(ax)
axis(ax, 'tight');
set(ax, 'yTickLabel', []);
set(ax, 'xTickLabel', []);
set(ax, 'Ticklength', [0 0]); % http://stackoverflow.com/a/15529630/54964
colormap(ax, 1-gray(1024));
box(ax, 'off');
axis(ax, 'off');
end
Outputs in the following, and Fig. 1 shows that the function can detect something on lines when the background is white but not on correct locations.
Linewidth Output
10 166x1 double
1 844x1 double
Table: full axis decoration in Test 1
Linewidth Output
10 []
1 []
Table: no axis decorations, after zeroFigureDecorations(hax) in Test 2
Fig. 1 line as input (See Bla's answer) and its output,
Fig. 2 Output is wrong in Section 2,
Fig. 3 One more example that you cannot apply to function to simple curves,
Fig. 4 Section 3 Output is wrong, since not known how to apply the function on spectrograms
2 Test with bla's example data
f0 = figure;
hax0 = axes(f0);
d=uint16(conv2(reshape(single( 2^14*(rand(1,128*128)>0.9995) ),[128 128]) ,fspecial('gaussian', 10,2),'same')+2^4*rand(128));
imagesc(d, 'Parent', hax0);
I = getframe(hax0);
I = I.cdata;
p=FastPeakFind(I);
hold(hax0, 'on');
plot(hax0, p(1:2:end),p(2:2:end),'r+')
hold(hax0, 'off');
Output is wrong in Fig. 2
3 Testing with spectrograms
f3 = figure;
hax3 = axes(f3);
N = 1024*10;
n = 0:N-1;
w0 = 2*pi/5;
x = sin(w0*n)+10*sin(2*w0*n);
s = spectrogram(x);
spectrogram(x,'yaxis')
p=FastPeakFind(s);
hold on;
plot(p(1:2:end),p(2:2:end),'r+')
Matlab: 2016b
OS: Debian 8.5
You are not using the function correctly.
your code is this (verbatim):
f = figure;
hax = axes(f);
af = figure('Name', 'Do Not Touch');
x = rand(1,100);
y = rand(1,100);
linewidth=1;
plot(hax, x,y, 'LineWidth', linewidth);
I = getframe(hax);
I = I.cdata;
The matrix I is not a matrix that contain peaks like the function is intended to have. This is how it looks like:
imagesc(I);
Even if all you had were single pixels, that is not what the function is supposed to have, as it is said that the peaks point spread function needs to be larger than some # of pixels, and that they are assumed to be sparse. The function has a demonstration on a sample image that works fine.
Also , it's completely unclear what you even mean by peaks here.
EDIT:
Here's an example of how to use the function. First let's select random positions where we "create" the peaks:
I=rand(200)>0.9995;
This makes a binary matrix with only the points larger than 0.9995 selected (or having value 1). At each step you can imagesc(I) to see how I looks.
In real life, a camera will have some intensity in these points so we write:
I=I*100;
This is important as the peak by dentition needs to be a maximum value in its neighborhood. In real life, peaks are mostly not single pixels, they have some "width" or spread (this is also what the function says it deals with):
I=conv2(I,fspecial('gaussian',10,2),'same');
here, this spread is done by a "point-spread function" of a guassian of some width.
Lets add some 30% noise (note that after the last step the maximum value of the peaks is no longer 100, because it is spread to other pixels as well):
I=I+0.3*max(I(:))*rand(size(I));
Let's find peaks
p=FastPeakFind(I);
See how it did:
subplot(1,2,1);imagesc(I);
subplot(1,2,2);imagesc(I); hold on
plot(p(1:2:end),p(2:2:end),'r+')
In the function code, the example is doing what I wrote here in a single line. Note that there is an edg parameter, as this will not work on peaks on the edges of the image. This cab be solved by padding the image with zeros I think...

MATLAB: how to customize non linear X axis (for example ticks at 1,2,3,4,5,20,100,'string')

I'm using the MATLAB plot feature to compare two vectors. I would like my X axis to represent 1 through 7, and then 14, 21, and then a category at the end for points with undetermined X values..(I'm also not sure how to represent these numberless point (they have Y values, just no X values) I could assign a large number outside any of my X values (1000) to these points, do the 1-7,14,21,1000 and then change the 1000 label to my 'string for un-numbered points'. ??
Here is a way to do it based on the example by The Mathworks here.
The trick is to create 2 x axis with different ranges and make one of them transparent. You can then play around with its properties. I modified a bit their code but kept most of their comments because they explain well the steps.
For the demo I used scatter to represent the points and colored the "good" points in red and the other point (here only 1) in green. You can customize all this of course. For instance I used a value of 100 and not 1000 for the x value of the 2nd axes, but I'll let you figure out how to modify it all to change the output as you wish.
clear
clc
close all
%// Create axes 1 and get its position
hAxes1 = axes;
axes_position = get(hAxes1, 'Position');
%// Create axes 2 and place it at the same position than axes 1
hAxes2 = axes('Position', axes_position);
%// Your data go here.
x = [1 7 14 21 100];
y = rand(1, length(x));
%// Plot the two sections of data on different axes objects
hPlot1 = scatter(hAxes1, x(1:4), y(1:4),40,'r','filled');
hold on
hPlot2 = scatter(hAxes2, x(end), y(end),40,'g','filled');
%// Link the y axis limits and fontsize property of the axes objects
linkaxes([hAxes1 hAxes2], 'y');
linkprop([hAxes1 hAxes2], 'FontSize');
%// Set the x range limits and tick mark positions of the first axes object
set(hAxes1, 'XLim', [1 25], ...
'XTick', [1 7 14 21])
%// Set the x range limits and tick mark positions for the second axes object.
%// Also set the background color to 'none', which makes the background
%// transparent.Add the label for the "super points".
set(hAxes2, 'Color', 'none', ...
'YTickLabel', [], ...
'XLim', [95 100], ...
'XTick', 100,'XTickLabel',{'Super Points'})
And the output:
EDIT
If you wish to add a fit line, I suggest adding a 3rd axes at the same position than the other 2, make it transparent and remove its X- and Y-ticks.
i.e. Add something like this:
hAxes3 = axes('Position', axes_position,'Color','none','YTick',[],'XTick',[]);
And in the call to polyfit/polyval, in my example you want to get only the first 4 elements (i.e. the red ones).
Hence:
p = polyfit(x(1:4),y(1:4),1);
y_poly = polyval(p,x(1:4));
And then plot the line on hAxes3:
hPlot3 = plot(x(1:4),y_poly)
Output:

draw a line of best fit through data with shaded region for error

I have the following data:
dat = [9.3,0.6,0.4,0.7;...
3.2,1.2,0.7,1.9;...
3.9,1.8,0.7,1.9;...
1.0,7.4,5.6,10.7;...
4.7,1.0,0.5,1.3;...
2.2,2.6,1.2,2.7;...
7.2,1.0,0.5,1.1;...
1.0,4.8,7.5,10.3;...
2.7,1.8,1.7,4.0;...
8.2,0.8,0.4,0.9;...
1.0,4.9,5.7,8.2;...
12.9,1.3,0.6,1.6;...
7.7,0.8,0.5,1.3;...
5.8,0.9,0.6,1.9;...
1.1,4.5,6.2,12.1;...
1.1,4.5,2.8,4.8;...
16.4,0.3,0.3,0.5;...
10.4,0.6,0.3,0.7;...
2.2,3.1,2.2,4.6];
where the first column shows the observed values the second column shows the modeled values and the third and fourth columns show the min and max respectively.
I can plot the relationship between observed and modeled by
scatter(d(:,1),d(:,2))
Next, I would like to draw a smooth line through these points to show the relationship. How can this be done? Obviously a simple straight line would not be much use here.
Secondly, I would like to use the min and max (3rd and 4th columns respectively) to draw a shaded region around the modeled values in order to show the associated error.
I would eventually like to have something that looks like
http://www.giss.nasa.gov/research/briefs/rosenzweig_03/figure2.gif
Something like this?
%// Rename and sort your data
[x,I] = sort(dat(:,1));
y = dat(I,2);
mins = dat(I,3);
maxs = dat(I,4);
%// Assume a model of the form y = A + B/x. Solve for A and B
%// using least squares
P = [ones(size(x)) 1./x] \ y;
%// Initialize figure
figure(1), clf, hold on
set(1, 'Renderer', 'OpenGl');
%// Plot "shaded" areas
fill([x; flipud(x)], [mins; flipud(maxs)], 'y',...
'FaceAlpha', 0.2,...
'EdgeColor', 'r');
%// Plot data and fit
legendEntry(1) = plot(x, P(1) + P(2)./x, 'b',...
'LineWidth', 2);
legendEntry(2) = plot(dat(:,1), dat(:,2), 'r.',...
'Markersize', 15);

Plotting subplots in a figure automatically for each column of matrix

For example let's say I have a following matrix (<9x6 double>) with a colheaders(<1x6 cell>).
Matrix =
226.7431 14.7437 14.9417 14.1000 14.5000 66.0590
226.7500 14.6582 14.8250 NaN 14.2000 66.7740
226.7569 14.3590 14.6067 NaN 13.9000 68.4897
226.7639 14.2702 14.5717 13.4000 13.8000 68.2487
226.7708 14.2555 14.6000 NaN 14.0000 NaN
226.7778 14.1605 14.5967 NaN 13.9000 NaN
226.7847 14.0320 14.4567 12.9000 13.6000 68.8272
226.7917 13.8422 14.2733 NaN 13.4000 69.6392
226.7986 13.6585 14.1169 NaN 13.1000 69.8048
I want to plot first column of matrix on x-axis and the rest on y-axis in a matlab figure with subplots (let's say 3 in one figure). Manually I can do something like this a figure and so on.
figure
subplot(3,1,1)
plot(Matrix(:,1),Matrix(:,2),'ro'); grid on; box on; xlabel('A');ylabel('B')
subplot(3,1,2)
plot(Matrix(:,1),Matrix(:,3),'bo'); grid on; box on; xlabel('A');ylabel('C')
subplot(3,1,3)
plot(Matrix(:,1),Matrix(:,4),'go'); grid on; box on; xlabel('A');ylabel('D')
and so on.....
......
......
Now here start a tricky part in which I required help from experts like you guys. I do not want to do manual plotting for my matrix as it consists on 200 columns. So what I want to do a automatic plotting of matrix, so that it plot every column of matrix in subplots. But 200 subplot can not come in one figures, so it start automatically a new figure after subplots limit(let's say 3). Beside I also need to define 'xlabel, ylabel,legend' automatically with a header file 'colheaders'. Is it possible?
x = rand(10, 200);
myYLabel = char(64+randi(26, 200, 1));
nrows = 3;
ncols = 2;
for ii = 1:size(x, 2)
if nrows*ncols-mod(-ii, nrows*ncols) == 1
figure;
end
subplot(nrows, ncols, nrows*ncols-mod(-ii, nrows*ncols));
plot(x(:, ii));
ylabel(myYLabel(ii, :));
end
It seems to be an easy for-loop task.
I assume you know before how much subplots you want in each figure (let's say 3).
A = yourdatamatrix;
header = [{'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}];
n = 6 %number of columns
i_figure = 1;
for ii=1:3:n-3
figure(ii)
subplot(3,1,1)
plot(A(:,1),A(:,ii+1),'ro'); grid on; box on; xlabel(header(1));ylabel(header(ii+1))
subplot(3,1,2)
plot(A(:,1),A(:,ii+2),'bo'); grid on; box on; xlabel(header(1));ylabel(header(ii+2))
subplot(3,1,3)
plot(A(:,1),A(:,ii+3),'go'); grid on; box on; xlabel(header(1));ylabel(header(ii+3))
end
I assume also you don't care about your figure number, otherwise just implement another counter.
Also be aware that the number of your columns+1 is divisible by 3.