Split Histogram - individual and total percentages display
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hello, I am trying to recreate something similar to the figure below. Currently, I can display the positive and negative in the respsective colours, but the code (also below) is coming up with the error "X must be same length as Y", which doesnt make sense to me with a histogram. Could someone help?
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/198255/image.png)
% Create 4D arrays that contain what is needed
TXxs = [];
TSAs = [];
% Loop through the five files - 001 to 005, read and save what is needed
num_files = 5;
for i = 1 : num_files
lat = ncread(sprintf('f.e122.F1850PDC5.f09_g16.control-io192.00%d_atm_h1_yearmean_selname.nc', i), 'lat');
lon = ncread(sprintf('f.e122.F1850PDC5.f09_g16.control-io192.00%d_atm_h1_yearmean_selname.nc', i), 'lon');
time = ncread(sprintf('f.e122.F1850PDC5.f09_g16.control-io192.00%d_atm_h1_yearmean_selname.nc', i), 'time');
TSA = ncread(sprintf('f.e122.F1850PDC5.f09_g16.control-io192.00%d_lnd_h1_yearmean_selname.nc', i), 'TSA');
TXx = ncread(sprintf('f.e122.F1850PDC5.f09_g16.control-io192.00%d_atm_h1_yearmean_selname.nc', i), 'TXx');
TXxs = cat(4, TXxs, TXx);
TSAs = cat(4, TSAs, TSA);
end
% Create storage for regression
% Number of lat and lon should be the same across all 5 files
% Also times should be the same
M = numel(lon);
N = numel(lat);
slope_TXx = zeros(M, N, num_files);
intercept_TXx = zeros(M, N, num_files);
slope_TSA = zeros(M, N, num_files);
intercept_TSA = zeros(M, N, num_files);
T = numel(time);
% Regress each lat/lon location
for i = 1 : M
for j = 1 : N
% Now go for each file
for k = 1 : num_files
% Get all time instances of each lat/lon location for TXx
y = squeeze(TXxs(i, j, :, k));
% Create regression problem and solve
x = [ones(T, 1) time];
%c = x \ y;
c = regress(y, x);
intercept_TXx(i, j, k) = c(1);
slope_TXx(i, j, k) = c(2);
% Repeat for TSA
y = squeeze(TSAs(i, j, :, k));
% Create regression problem and solve
%x = [ones(T, 1) time];
%c = x \ y;
c = regress(y, x);
intercept_TSA(i, j, k) = c(1);
slope_TSA(i, j, k) = c(2);
end
end
end
% Statistics work
% Unroll into a single vector and remove NaN values for TXx
slopes = slope_TXx(:);
slopes(isnan(slopes)) = [];
h=histogram(slopes(slopes>0));
h.FaceColor='red';
hold on
h1=histogram(slopes(slopes<0));
h1.FaceColor='blue';
ylim([0 11000]);
xlim([-0.0004 0.0005]);
title('Distribution of all M slopes - CTL TXx');
binranges = -0.0004:0.0005;
[bincounts] = h(x,binranges);
%Compute percent contributions
percentagevalues = bincounts./sum(bincounts) * 100;
%Create a histogram
figure
bar(binranges,bincounts,'h')
for i = 1:length(bincounts)-1
%Determine x location of label
x = (binranges(i) + binranges(i+1))/2;
%Determine y location of label, offset it by some distance from the
%top of the bar
y = bincounts(i)+1;
%Create a text object
text(x,y,num2str(bincounts(i),'%3.2f'),'HorizontalAlignment','center');
end
2 commentaires
Réponses (1)
Star Strider
le 4 Déc 2018
The problem is with your ‘binranges’ assignment. The colon (link) operator increments by default by 1, so the result of:
binranges = -0.0004:0.0005;
is:
binranges =
-0.0004
I would do this:
N = 10; % Number Of Bins
binranges = linspace(-0.0004, 0.0005, N);
or specify an increment step size:
binranges = -0.0004 : 0.0001 : 0.0005;
depending on the result you want.
4 commentaires
Star Strider
le 4 Déc 2018
You will need to calculate the percentages.
To display them as values on the top of each bar, this works:
y1 = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
hBar = bar(y1,1); % Return ‘bar’ Handle
for k1 = 1:size(y1,2)
ctr(k1,:) = bsxfun(@plus, hBar(1).XData, hBar(k1).XOffset'); % Note: ‘XOffset’ Is An Undocumented Feature, This Selects The ‘bar’ Centres
ydt(k1,:) = hBar(k1).YData; % Individual Bar Heights
text(ctr(k1,:), ydt(k1,:), sprintfc('%.1f', log(ydt(k1,:))), 'HorizontalAlignment','center', 'VerticalAlignment','bottom', 'FontSize',8, 'Color','b')
end
It labels the top of each bar with the natural logarithm of the bar value, so you will need to adapt that to your percentages. (You can replace the sprintfc call with a compose call if you want.) I cannot run your code, so you will need to adapt it yourself. You will have to get the histogram counts and plot them as a bar plot for this to work. I am not certain it will work with a histogram plot (I’ve never tried it), although it might with a bit of ingenuity.
Voir également
Catégories
En savoir plus sur Histograms dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!