MATLAB Answers

How to draw a 2D histogram from a time series?

조회 수: 33(최근 30일)
Stepan Subik
Stepan Subik 2020년 4월 3일
댓글: Image Analyst 2020년 4월 5일
Hello,
I have a data from a meteorological station measuring temperature each hour from 1990 to 2020 and I have the data as table of datetime and double. I would like to draw a histogram like this:
Do you have any ideas? I have found the hist3 function, but the documentation does not explain the usage of the function clearly for me.
EDIT: The data are included
  댓글 수: 4
Stepan Subik
Stepan Subik 2020년 4월 4일
Hi, thank you for your reaction. Here are the data in .csv (not whole data due to upload restrictions).

댓글을 달려면 로그인하십시오.

채택된 답변

Stepan Subik
Stepan Subik 2020년 4월 5일
I have found out the solution:
load('temp_data.mat')
table = table2timetable(temperature);
table = retime(table, 'daily', 'mean');
table = timetable2table(table);
idx = year(table{:,'Zeitstempel'}) == 2004;
refYear = table{idx,'Zeitstempel'};
N = [];
edges = [-9999 -10 0 4 8 13 18 23 29 35 41 9999];
for i = 1:length(refYear)
idx = month(table{:,'Zeitstempel'}) == month(refYear(i)) & day(table{:,'Zeitstempel'}) == day(refYear(i));
newtable = table(idx, :);
N{i} = histcounts(newtable{:, 'AirTemp'}, edges);
end
plotVal = [N{1,1};N{1,2}];
for i = 3:length(N)
plotVal = [plotVal;N{1,i}];
end
plotVal = bsxfun(@rdivide, plotVal, sum(plotVal,2));
h = area(plotVal);
h(1).FaceColor = [0 0 1];
h(2).FaceColor = [0.1 0 0.9];
h(3).FaceColor = [0.2 0 0.8];
h(4).FaceColor = [0.3 0 0.7];
h(5).FaceColor = [0.4 0 0.6];
h(6).FaceColor = [0.5 0 0.5];
h(7).FaceColor = [0.6 0 0.4];
h(8).FaceColor = [0.7 0 0.3];
h(9).FaceColor = [0.8 0 0.2];
h(10).FaceColor = [0.9 0 0.1];
h(11).FaceColor = [1 0 0];
grid on
colormap summer
set(gca,'Layer','top')
title 'Stacked Area Plot'
But do you know how to add the scale bar of the values from edges?

추가 답변(2개)

darova
darova 2020년 4월 4일
My proposition
A = importdata('temp_data.csv',',');
temp = A.data;
time = A.textdata;
time(:,2) = [];
time(1) = [];
% calculate size for matrix
n = (year(time(end))-year(time(2))+1)*12; % number of columns
m = 24*31; % numer of rows
P = nan(m,n); % preallocate matrix
% calculate appropriate position in matrix
ii = hour(time) + (day(time)-1)*24 + 1; % rows
jj = month(time) + (year(time)-year(time(1)))*12; % columns
ind = sub2ind(size(P),ii,jj);
P(ind) = temp; % fill matrix
imagesc(P)
colorbar
xlabel('months')
ylabel('hour + 24*day')
axis xy
Those short blue lines at the top are months with 30 days
Long blue lines - february 28/29 days
  댓글 수: 3
Stepan Subik
Stepan Subik 2020년 4월 4일
Well, thank you for your answer, but it is not what I am searching for. I would like to define a scale (shown in the rigth bar of the picture) to make a histogram for each day (or hour - that is not important for its easy calculations in timetable format) to see the ammount of values for each one day (e.g. 4.4.) in those years. Then I would like to plot that in a one picture showing all of those days in a year (as is shown in the picture).

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2020년 4월 4일
Your image doesn't really make sense. You can't have both the y axis and the color both indicate the frequency (counts of each temperature). So, try this:
% Initialization steps.
clc; % Clear the command window.
fprintf('Beginning to run %s.m ...\n', mfilename);
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
fileName = 'temp_data.mat'
s = load(fileName)
tbl = s.temperature;
dateTimes = tbl.Zeitstempel;
temperatures = tbl.AirTemp;
hFig = figure;
subplot(2, 1, 1);
plot(dateTimes, temperatures, 'b.');
grid on;
title('Temperatures by Date', 'FontSize', fontSize);
xlabel('Date', 'FontSize', fontSize);
ylabel('Temperature', 'FontSize', fontSize);
% Get the month for each date/time stamp
theMonths = month(dateTimes);
% Make up a histogram of 100 bins for each month
edges = [-inf, -10, 4, 4, 8, 13, 18, 23, 29, 35, 41, inf];
% Make up the output image.
tempHistImage = zeros(length(edges) - 1, 12); % 100 bins, 12 months. Each month is a column.
for k = 1 : 12
rowsForThisMonth = theMonths == k;
tempsForThisMonth = temperatures(rowsForThisMonth);
counts = histcounts(tempsForThisMonth, edges);
% Load into an image
tempHistImage(:, k) = counts;
end
% Replicate the image to make it wider.
% tempHistImage = imresize(tempHistImage, [100, 12*10], 'nearest');
subplot(2, 1, 2);
imshow(tempHistImage, [], 'InitialMagnification', 800);
colormap(jet(length(edges)));
colorbar;
axis('on', 'image');
title('Temperature Histogram, by Month', 'FontSize', fontSize);
xlabel('Month', 'FontSize', fontSize);
ylabel('Temperature', 'FontSize', fontSize);
hFig.WindowState = 'maximized'; % Maximize the window.
fprintf('Done running %s.m ...\n', mfilename);
You can fancy it up further if you want, like with tick labels, etc.
  댓글 수: 2
Image Analyst
Image Analyst 2020년 4월 5일
Well let's look at your plot for the first week of August. The orange strip where the temperature is between 23 and 29 degrees. Can you tell me, looking at your y axis, what percentage of days in August have a termperature between 23 and 29 degrees? Is it 45% of the days? 50%? 65% How can you tell from the graph? Now, there really is an answer. If you looked at all the values, you might be, say 58%, but from your graph there's no telling.

댓글을 달려면 로그인하십시오.

범주

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by