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

17 views (last 30 days)
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 Comments
darova
darova on 4 Apr 2020
Maybe you want imagesc? Can you upload the data in another format? I have older version, can't read
Stepan Subik
Stepan Subik on 4 Apr 2020
Hi, thank you for your reaction. Here are the data in .csv (not whole data due to upload restrictions).

Sign in to comment.

Accepted Answer

Stepan Subik
Stepan Subik on 5 Apr 2020
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?

More Answers (2)

darova
darova on 4 Apr 2020
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 Comments
darova
darova on 4 Apr 2020
I decided not to do that. My answer - my rules
Stepan Subik
Stepan Subik on 4 Apr 2020
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).

Sign in to comment.


Image Analyst
Image Analyst on 4 Apr 2020
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 Comments
Stepan Subik
Stepan Subik on 4 Apr 2020
Yes, the second graph looks almost perfect. I did not know that my picture can look like it dous not make sense. I will explain more. First you get the average temperature for each day in all those 30 years. Than for each day in a year you calculate the frequency of the temperature belonging to the cathegories plotted on the right side (below -10, between -10 and 0) when you have the frequencies, you can plot the "bar" plot, where for each day in a year you just show how much percent of the cases belonged to first category, second category,....)
Therefore the y axis is the frequency and the color describes the category (plotted on the right side)
Image Analyst
Image Analyst on 5 Apr 2020
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.

Sign in to comment.

Categories

Find more on Discrete Data Plots in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!