Matlab : Combined histograms - matlab

I try to combine with a "hold on" several histograms that I get from several figures. The figures have the same X axis that I defined. Nevertheless I can't display. Would you have a solution?
close all;
clearvars;
xlimArr = [0 0.05];
dataset = xlsread('DEHS_REF.xlsx', 'Feuil1', 'A2:B47');
h0=hgload('Données_LOAC_n°0_DEHS_1');
h1=hgload('Données_LOAC_n°1_DEHS_1');
h2=hgload('Données_LOAC_n°2_DEHS_1');
h3=hgload('Données_LOAC_n°3_DEHS_1');
g0 = findobj(h0, 'type', 'Histogram');
g1 = findobj(h0, 'type', 'Histogram');
g2 = findobj(h0, 'type', 'Histogram');
g3 = findobj(h0, 'type', 'Histogram');
hist_chanel_1 = g0(2);
hist_chanel_2 = g1(2);
hist_chanel_3 = g2(2);
hist_chanel_4 = g3(2);
figure();
histogram(hist_chanel_1.Data, 'BinWidth', hist_chanel_1.BinWidth);
hold on
histogram(hist_chanel_2.Data, 'BinWidth', hist_chanel_2.BinWidth);
histogram(hist_chanel_3.Data, 'BinWidth', hist_chanel_3.BinWidth);
histogram(hist_chanel_4.Data, 'BinWidth', hist_chanel_4.BinWidth);
hold off
xlabel('Value [V]');
ylabel('Nb of peak');
title('AerosolsGenerator peak distribution (amplitude)');
xlim(xlimArr); ```

I am coming back to you having found the answer partially. I don't know why but taking the sorted data from a histogram doesn't allow to superimpose them. By taking directly the variables of the workspace allows to remake the histograms and to overlay them
% ANALYSE DEHS MEASURE LOAC V2
% Paul Miailhe - jannuary 2022
% Last modification: jannuary 2022 by Paul Miailhe.
%% Load variable
close all;
clearvars;
xlimArr = [0 0.05];
channel1_LOAC0 = load('chanel1_LOAC_n°0.mat');
channel1_LOAC1 = load('chanel1_LOAC_n°1.mat');
channel1_LOAC2 = load('chanel1_LOAC_n°2.mat');
channel1_LOAC3 = load('chanel1_LOAC_n°3.mat');
channel2_LOAC0 = load('chanel2_LOAC_n°0.mat');
channel2_LOAC1 = load('chanel2_LOAC_n°1.mat');
channel2_LOAC2 = load('chanel2_LOAC_n°2.mat');
channel2_LOAC3 = load('chanel2_LOAC_n°3.mat');
%% Graphique :
%Channel 1
h(1) = figure;
subplot(2,1,1);
histogram(channel1_LOAC0.data_channel1, channel1_LOAC0.bins)
hold on
histogram(channel1_LOAC1.data_channel1, channel1_LOAC1.bins)
histogram(channel1_LOAC2.data_channel1, channel1_LOAC2.bins)
histogram(channel1_LOAC3.data_channel1, channel1_LOAC3.bins)
hold off
xlabel('Value [V]');
ylabel('Nb of peak');
title('CH1 result distribution (amplitude)');
legend('show');
xlim(xlimArr);
%Channel 2
subplot(2,1,2);
histogram(channel2_LOAC0.data_channel2, channel2_LOAC0.bins)
hold on
histogram(channel2_LOAC1.data_channel2, channel2_LOAC1.bins)
histogram(channel2_LOAC2.data_channel2, channel2_LOAC2.bins)
histogram(channel2_LOAC3.data_channel2, channel2_LOAC3.bins)
hold off
xlabel('Value [V]');
ylabel('Nb of peak');
title('CH2 result distribution (amplitude)');
legend('show');
xlim(xlimArr);

Related

Weibull Curves plotting

I want to plot 2 weibull curves( sample and model) on the same graph.
I have worked in my code.
Attached is the results i am having, i do not want the bar chart present, only my 2 weibull curves, but I am not able to do it.
Can someone please help me???
ps: In this case, #Guto has helped me edit my codes and now they work wonderfully.
Thanks
sample=[4.6
3.6
2.3
2.3
3
3.1
];
model=[8.01
6.75
6.57
6.07
5.94
5.58
];
% --- Plot data originally in dataset "sample data"
[CdfF,CdfX] = ecdf(sample,'Function','cdf'); % compute empirical cdf
BinInfo.rule = 1;
[~,BinEdge] = internal.stats.histbins(sample,[],[],BinInfo,CdfF,CdfX);
[BinHeight,BinCenter] = ecdfhist(CdfF,CdfX,'edges',BinEdge);
hLine = bar(BinCenter,BinHeight,'hist');
set(hLine,'FaceColor','none','EdgeColor',[0.333333 0 0.666667],...
'LineStyle','-', 'LineWidth',1);
xlabel('Data');
ylabel('Density')
LegHandles(end+1) = hLine;
LegText{end+1} = 'sample data';
% Create grid where function will be computed
XLim = get(gca,'XLim');
XLim = XLim + [-1 1] * 0.01 * diff(XLim);
XGrid = linspace(XLim(1),XLim(2),100);
% --- Create fit "Weibull"
% Fit this distribution to get parameter values
pd3 = fitdist(sample, 'weibull');
YPlot = pdf(pd3,XGrid);
hLine = plot(XGrid,YPlot,'Color',[0.666667 0.333333 0],...
'LineStyle','-', 'LineWidth',2,...
'Marker','none', 'MarkerSize',6);
dist = makedist('Weibull','a',pd3.ParameterValues(1),'b',pd3.ParameterValues(2))
[h_ad_weibull, p_ad_weibull, adstat_weibull,cv_ad_weibull]= adtest(sample,'Distribution','weibull')
[h_ks_weibull, p_ks_weibull, ksstat_weibull,cv_ks_weibull]= kstest(sample,'CDF',dist)
LegHandles(end+1) = hLine;
LegText{end+1} = 'Weibull';
box on;
figure(1);
hold on;
% --- Plot data originally in dataset "model data"
[CdfF,CdfX] = ecdf(model,'Function','cdf'); % compute empirical cdf
BinInfo.rule = 1;
[~,BinEdge] = internal.stats.histbins(model,[],[],BinInfo,CdfF,CdfX);
[BinHeight,BinCenter] = ecdfhist(CdfF,CdfX,'edges',BinEdge);
hLine = bar(BinCenter,BinHeight,'hist');
set(hLine,'FaceColor','none','EdgeColor',[0.333333 0 0.666667],...
'LineStyle','-', 'LineWidth',1);
xlabel('Data');
ylabel('Density')
LegHandles(end+1) = hLine;
LegText{end+1} = 'model data';
% Create grid where function will be computed
XLim = get(gca,'XLim');
XLim = XLim + [-1 1] * 0.01 * diff(XLim);
XGrid = linspace(XLim(1),XLim(2),100);
% --- Create fit "Weibull"
% Fit this distribution to get parameter values
pd3 = fitdist(model, 'weibull');
YPlot = pdf(pd3,XGrid);
hLine = plot(XGrid,YPlot,'Color',[0.666667 0.333333 0],...
'LineStyle','-', 'LineWidth',2,...
'Marker','none', 'MarkerSize',6);
dist = makedist('model','a',pd3.ParameterValues(1),'b',pd3.ParameterValues(2))
[h_ad_weibull, p_ad_weibull, adstat_weibull,cv_ad_weibull]= adtest(model,'Distribution','weibull')
[h_ks_weibull, p_ks_weibull, ksstat_weibull,cv_ks_weibull]= kstest(model,'CDF',dist)
LegHandles(end+1) = hLine;
LegText{end+1} = 'Weibull';
box on;
figure(2);
There are a few options to solve your problem. There are the two that came to my mind:
Remove the bar plots and make the limit.
If you don't want the bar plots why are you plotting it? Your code use it as input, but there is no reason to not use the limits from the data itself. Maybe you use for other purposes in another part not show. If this is the case, use the option 2.
For this, you just need fitdist and pdf functions. However, you need to check the min and max of both data sets and uses whatever is smaller or bigger. Here is just the necessary code to plot both lines:
box on; %create a figure and hold it
hold on;
%CREATE A GRID FROM DATA
XGrid=linspace(min(min([sample model]))-0.4*min(min([sample model])),...
max(max([sample model]))+0.2*max(max([sample model])),100);
% --- Create fit "Weibull"
% Fit this distribution to get parameter values
pd3 = fitdist(sample, 'weibull');
YPlot = pdf(pd3,XGrid);
hLine = plot(XGrid,YPlot,'Color',[0.666667 0.333333 0],...
'LineStyle','-', 'LineWidth',2,...
'Marker','none', 'MarkerSize',6);
% --- Create fit "Weibull"
% Fit this distribution to get parameter values
pd3 = fitdist(model, 'weibull');
YPlot = pdf(pd3,XGrid);
hLine = plot(XGrid,YPlot,'Color',[0.666667 0.333333 0],...
'LineStyle','-', 'LineWidth',2,...
'Marker','none', 'MarkerSize',6);
xlabel('Data');
ylabel('Density')
Delete the graph
That is quite straightforward and require only a small change. In the part % --- Plot data originally in dataset "model data", after the command set(hLine,'FaceColor' ... put the another command:
delete(hLine)
It will remove the latest graph assigned to hLine, that are the bars.
This will give the same output (except by small variations on limits) as above.

Putting one legend for many axes

I'm using three axes-Objects to scale my data on the x-axis.
My problem is that i do not know how to get a nice legend for the three plots.
I have to do this cause my real data is sampled with different sample rates.
I edited my m-file for the diagram slightly cause normally I'm reading the data out of some txt files.
In this example i used example_data 1 to 3 for my data.
In this example I'm scaling the example_data1 so it looks like the same frequency as example_data2.
I do the 'scaling' ax1.XLim = [0 length(x2)].
That's why this solution doesn't work for me: Plot with multiple axes but only one legend.
It uses set(l3,'Parent',ax2); which somehow ruins my approache to scale my data. The scaling is the only solution to my problem cause i don't know the exact relation between the two sampling rates.
my code:
example_data1 = repmat(1:100,1,10);
example_data2 = 2 * repmat(1:0.5:100.5,1,5);
example_data3 = [1:500 500:-1:1];
whole_length_data1 = length(example_data1);
% 1. step
start_of_data = 1;
end_of_data = 1000;
% data2
y2 = example_data2(start_of_data:end_of_data);
x2 = 0:length(y2)-1;
% data3
y3 = example_data3(start_of_data:end_of_data);
x3 = 0:length(y3)-1;
% data1
y1 = example_data1(1:length(example_data1));
x1 = 0:length(y1)-1;
% 2. step
start_one = 1;
y1 = example_data1(start_one:length(example_data1));
x1 = 0:length(y1)-1;
% 3.step
end_one = whole_length_data1 - 500;
y1 = example_data1(start_one:end_one);
x1 = 0:length(y1)-1;
Farbe1 = [0,1,0]*0.6; % Dunkelgrün
Farbe2 = [1,0,0]*0.8; % Dunkelrot
Farbe3 = get(groot,'DefaultAxesColorOrder') % default values
Farbe3 = Farbe3(1,:); % 1. Zeile der defaultvalues
figure(1)
% 3 axes
clf
%------------------------------------------------------------------
%-------------------------- plot1: ---------------------------
%------------------------------------------------------------------
plot(x2,y2,'green','LineWidth',2,'Color',Farbe1,...
'DisplayName','name of the first plot')
ax1 = gca;
ax1.XLim = [0 length(x2)]
ax1.YLim = [min(y2) max(y2)]
ax1.YTick = [0:25:300]
ax1.FontSize = 12;
legend('show')
%----------------------------------------------------------------
%-------------------------- plot2: --------------------------
%----------------------------------------------------------------
ax2 = axes('Position',ax1.Position);
plot(x3,y3,'blue','LineWidth',2,'Color',Farbe3,...
'DisplayName','plot2')
ax2.Color = 'none';
ax2.XTick = [];
ax2.XLim = [0 length(x3)];
ax2.YAxisLocation = 'right';
ax2.FontSize = 12;
legend('show')
%----------------------------------------------------------------
%-------------------------- plot3: -------------------------
%----------------------------------------------------------------
ax3 = axes('Position',ax1.Position);
plot(x1,y1,'red','LineWidth',2,'Color',Farbe2,...
'DisplayName','3')
ax3.XTick = [];
ax3.YTick = [];
ax3.Color = 'none';
ax3.XAxisLocation = 'top';
ax3.YAxisLocation = 'right';
ax3.XLim = [0 length(x1)];
ax3.YLim = [min(y1) max(y1)*2];
legend('show')
This results in a very bad looking legend:
I really hope somebody can help me.
Thank very much.
You can get better results by storing handles for each of your plot lines, then passing those to a single legend call:
...
h1 = plot(x2,y2,'green','LineWidth',2,'Color',Farbe1,...
'DisplayName','name of the first plot');
...
h2 = plot(x3,y3,'blue','LineWidth',2,'Color',Farbe3,...
'DisplayName','plot2');
...
h3 = plot(x1,y1,'red','LineWidth',2,'Color',Farbe2,...
'DisplayName','3');
...
hl = legend(ax3, [h1 h2 h3]); % Place legend in top-most axes
And here's the result:
Just use the real timestamps as x values:
fig = figure;
plot(x1/length(y1)*end_of_data, y1, 'LineWidth',2, 'Color',Farbe1, 'DisplayName','First plot')
hold on
plot(x2/length(y2)*end_of_data, y2, 'LineWidth',2, 'Color',Farbe2, 'DisplayName','Second plot')
plot(x3/length(y3)*end_of_data, y3, 'LineWidth',2, 'Color',Farbe3, 'DisplayName','Third plot')
legend

How to find peaks in an image using matlab?

I am trying to outline all peaks in an image. The brightest lines are the peaks. I am using Matlab. This is what I have so far....
Any help will be greatly appreciated. Here is the image.
a = imread('duneLiDARs.png');
%b = imregionalmax(a);
%a = rgb2gray(a);
c = edge(a,'Sobel');
b = edge(a,'log',.0006);
d = edge(a,'log');
c= imfuse(a,d);
d= d-b;
subplot(2,2,1), imshow(a)
subplot(2,2,2), imshow(b)
subplot(2,2,3), imshow(c)
subplot(2,2,4), imshow(d)
%imshow(b);
%c = imadd(a,b);
%imshow(b);
you need to define what do you consider as peaks - what is the desired output for your image.
however, there are some general 2D peaks finding function, the following code uses FEX's extrema2:
% load image and remove extreme noise
im = medfilt2( im2double(imread('dune.png')));
% find peaks using extrema2
[XMAX,IMAX,XMIN,IMIN] = extrema2(im);
% eliminate peaks under minimum threshold
underThresh = XMAX < 0.15;
IMAX(underThresh) = [];
XMAX(underThresh) = [];
% plotting
subplot(121);
surf(im,'EdgeColor','none');
hold on;
[y,x] = ind2sub(size(im),IMAX);
scatter3(x,y,XMAX,'r','filled');
axis square
subplot(122);
imshow(im,[]);
hold on;
scatter(x,y,'r','filled');

How to smooth the edges in my contour plot corresponding to nan

This is the link to the dataset. I have this contour plot which has a bit rough edges. My question is, how can I smooth these edges these edges correspond to Nan. I filled in the Z matrix with Nan so as to remove unwanted values.
I also wanted to ask that why shading flat and interp is not working on this contour.
I have set shading to flat and in Matlab2013b I get proper flat figure but in Matlab 2014b and 2015b I am getting this figure.
MATLAB 2015b:
MATLAB 2013b
How can I obtain perfectly meshed plot in Matlab 2015b, I checked for shading options in the documentation and there are only 3 faceted, interp and flat.
shading flat works in 2013b but not in subsequent versions. Can someone tell me why is it so?
This is the sample code which I am using right now:
clear all; close all; clc;
load temperature.txt;
time = temperature(:,1); % This column contains the time
x = temperature(:,2); % This column contains the x values.
temperature_system = temperature(:,3); % This column contains the temperatures.
% Rejecting the outliers
pos = (temperature_system > prctile(temperature_system,97));
time(pos) = [];
x(pos) = [];
temperature_system(pos) = [];
X1 = [time x];
F = scatteredInterpolant(X1,temperature_system);
x1 = linspace(min(x),max(x),100);
x2 = linspace(min(time),max(time),100);
[X,Y] = meshgrid(x2,x1);
Z = F(X,Y);
% Is the data below the criteria for all points in space at a specific time
emptyTime = all(Z<10,1);
emptySpace = all(Z<10,2);
[emptyTime, emptySpace] = meshgrid(emptyTime, emptySpace);
Z(emptyTime | emptySpace) = nan;
% Replacing the remaining zeros with nan
pos = find(Z<1);
Z(pos) = nan;
f1 = figure(1);
%set(f1,'renderer','zbuffer');
%surf(X,Y,Z);
[C,h] = contourf(X,Y,Z, 'Linestyle', 'none');
shading flat;
colormap(jet);
q = colorbar;
set(q,'direction','reverse');
q.Label.String = 'Temperature';
xlabel('Time (ps)','FontSize', 16, 'FontWeight', 'bold',...
'FontName', 'Helvetica', 'Color', 'Black');
ylabel('Length of box (A)','FontSize', 16, 'FontWeight', 'bold',...
'FontName', 'Helvetica', 'Color', 'Black');
set(gca,'LineWidth',3,'TickLength',[0.02 0.02]);
set(gca,'XMinorTick','on');
set(gca,'YMinorTick','on','XTicksBetween', 5);
set(gca,'FontSize',12,'FontName','Helvetica');
It's difficult to test the issue without having your data. I got rid of the lines by means of the LineStyle property:
Code:
Z = peaks(20);
subplot(2,1,1);
contourf(Z,10);
colorbar;
subplot(2,1,2);
contourf(Z,10, 'LineStyle', 'none');
colorbar;

How can I plot a Quarter graph in matlab?

I wanna to plot a graph as the below:
And this one:
I was doing something like this:
cc=hsv(ns);
hold on;
for nk=1:ns
figure(4); hold on;
h=plot(M1(nk,:),':','color',cc(nk,:));
set(h,'linewidth',2)
end
How can I do it?
For the first plot you just need to use plot and text plus some tweaking. If you want the legend in two columns, have a look at columnlegend in the Matlab File Exchange.
% generate some data
days = (1:250);
M1 = (days'*[0.06,-0.03,0.02,-0.04,0.05,-0.05,0.01])';
M1 = M1 + 0.5*randn(size(M1));
years = 2002+(1:size(M1,1));
ns = size(M1,1);
% prepare plot
figure(4); hold on;
cc = hsv(ns);
% plot all prices
for nk = 1:ns
ph = plot(days,M1(nk,:),'Color',cc(nk,:));
set(ph,'LineWidth',2);
end
% plot texts
for i = 1:4
h = text(250/8+(i-1)*250/4,18,['Q',num2str(i)]);
set(h,'FontSize',13,'HorizontalAlignment','center');
end
% plot vertical lines and the horizontal line
plot([250,250]'*(0:4)/4,[-21,21],'k-.');
plot([-10,250+10],[0,0],'k-.');
% set limits
set(gca,'XLim',[-10,250+10]);
set(gca,'YLim',[-21,21]);
% set labels and legend
xlabel('Day of Trading');
ylabel('Normalized Price');
lh = legend(cellstr(num2str(years')),'Location','SouthWest');
set(lh,'FontSize',8);
% tweak appearance
set(gca,'YTick',-20:10:20);
set(gca,'FontSize',13);
set(gca,'GridLineStyle',':');
grid on;
box on;
This is the result:
The second plot is very similar to the first one. For the confidence interval you can use fill. Because the entries in the legend have a different order as the order of plotting them, we store the handles and give it as the first argument to legend.
% generate some data
rng(2);
days = (1:250);
realised_Q1 = (1:62)*0.04+0.5*randn(1,62);
realised_Q234 = realised_Q1(end)+(1:189)*0.03+0.5*randn(1,189);
forecast_Q234 = realised_Q1(end)-3*sin((1:189)/40);
confidence_up = forecast_Q234+(1-exp(-(0:188)/10));
confidence_down = forecast_Q234-(1-exp(-(0:188)/10));
% prepare plot
figure; hold on;
ph = zeros(4,1);
% plot confidence interval
ph(4) = fill([days(62:250),fliplr(days(62:250))],...
[confidence_up,fliplr(confidence_down)],...
[0.85,0.85,1],'EdgeColor','none');
% plot realized Q1
ph(1) = plot(days(1:62),realised_Q1,'r','LineWidth',2);
% plot realized Q2 Q3 Q4 and forecast Q2 Q3 Q4
ph(2) = plot(days(62:250),realised_Q234,'k','LineWidth',2);
ph(3) = plot(days(62:250),forecast_Q234,'b','LineWidth',2);
% plot texts
for i = 1:4
h = text(250/8+(i-1)*250/4,13,['Q',num2str(i)]);
set(h,'FontSize',13,'HorizontalAlignment','center');
end
% plot vertical lines and the horizontal line
plot([250,250]'*(0:4)/4,[-21,21],'k-.');
plot([-10,250+10],[0,0],'k-.');
% set limits
set(gca,'XLim',[-10,250+10]);
set(gca,'YLim',[-6,16]);
% set labels and legend
xlabel('Day of Trading');
ylabel('Normalized Price');
lh = legend(ph,'Realized Q1 (2011)','Realized Q2 Q3 Q4 (2011)',...
'Forecast Q2 Q3 Q4 (2011)','Confidence',...
'Location','SouthWest');
set(lh,'FontSize',8);
% tweak appearance
set(gca,'YTick',-5:5:15);
set(gca,'FontSize',13);
set(gca,'GridLineStyle',':');
grid on;
box on;
This is the result: