How to plot multiple year data over common months?

Dear all,
how to plot data from multiple years over one common x-axis? I have some test data measured in january over 4 years, and I want to color the data corresponding the different years. This testdata (datetime data & measurement data) containts data for January only, however future measurements may contain other months, too. So I would like to have x.axis ticks 1-12 (months) and user a scatterplot(?) to mark the points corresponding to n years (colormarker). Please find the test data attached and many thanks for help in advance!
dt=readtable("Test.xlsx");
plot (dt.Date, dt.NO2,"r.")

1 Comment

Please provide more data. There is only one month (January) for all four years in that file excerpt.

Sign in to comment.

 Accepted Answer

With different markers as well as different colors (different colors alone is easier.)
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/853865/Test.xlsx';
dt = readtable(filename);
[y, m, d] = ymd(dt.Date);
baseyear = min(y);
lastyear = max(y);
cmap = colormap(jet(lastyear-baseyear+1));
G = y - baseyear + 1;
x = datetime(baseyear, m, 1, 'Format', 'MM');
pointsize = 30;
markers = {'.', '+', '*', '<', 'o', 's'}.';
assert(length(markers) >= max(G), 'Need more markers');
markermap = markers(G);
hold on
splitapply(@(M,NO2,c,mark) scatter(M, NO2, pointsize, c(1,:), mark{1}), x, dt.NO2, cmap(G,:), markermap, G);
%scatter(x, dt.NO2, pointsize, cmap(y-baseyear+1,:));
hold off
xlim auto; ylim auto;
ax = gca; ax.XRuler.TickLabelFormat = 'MMM';
xticks(datetime(baseyear,1:12,1))

8 Comments

Many thanks; this is very helpful, and indeed different colors are enough. Hoewever I am wondering about the year 2017-2018 in the lower right corner (the timerange should be 2017-2021 with the test data). And, could you also help me to add a legend providing information about colors and years?
I have modified your code in order to see the different days within the single months:
dt=readtable("Test.xlsx");
d = day(dt.Date,'dayofmonth');
m = month(dt.Date);
y = year(dt.Date);
baseyear = min(y);
lastyear = max(y);
cmap = colormap(jet(lastyear-baseyear+1));
x = datetime(baseyear, m, d, 'Format', 'MM:dd');
pointsize = 30;
hold on
scatter(x, dt.NO2, pointsize, cmap(y-baseyear+1,:));
hold off
ax = gca; ax.XRuler.TickLabelFormat = 'MMM DD';
xticks(datetime(baseyear,1:12,1))
axis(ax, 'tight')
xlim(ax, xlim(ax) + [-1,1]*range(xlim(ax)).* 0.05)
ylim([0 5])
title ("title")
ylabel ("title")
legend
However; I still cannot add a proper legend representing the different years related to the colors. Moreover, I am still wondering how to erase the note '2017-2018' in the lower corner. I understand this is an artefact of how one has to trick matlab to plot multiple years over one year, however I still do not want present this in the plot.
Many, many thanks!
I was hoping you would not ask me about the year -- it is difficult enough to remove that a different way of drawing is suggested.
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/853865/Test.xlsx';
dt = readtable(filename);
[y, m, d] = ymd(dt.Date);
baseyear = min(y);
lastyear = max(y);
cmap = colormap(jet(lastyear-baseyear+1));
G = y - baseyear + 1;
pointsize = 30;
scatter(m, dt.NO2, pointsize, cmap(G,:));
xlim([.5 12.5])
xticks(1:12);
xticklabels({'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'})
hold on
nG = max(G);
L = gobjects(1, nG);
for K = 1 : nG;
L(K) = plot(nan, nan, 'color', cmap(K,:));
end
hold off
legend(L, string(baseyear:lastyear))
Wow; this is great - would it also be possible to include the dayofmonth into this?
Do you want each month to occupy 1/12 of the range, or do you want each month to occupy the portion of the range corresponding to the length of the month?
How do you want to handle February 29, 2020? Do you want each day's data to be placed at a location proportional to it's fraction of a year, which makes sense in some ways but could result in the 2020 data being just slightly out of alignment with the rest of the data.
Or shold February 29 information just be dropped?
JMSE
JMSE on 5 Jan 2022
Edited: JMSE on 5 Jan 2022
I would like each month to occupy 1/12 of the year and do not mind too much about Feb 29. I think this would be easiest to use while adding future measurements.
Actually, would it not be simpler to split the datetime into 2 arrays (1: day and months; 2: year) and to scatter it with scatter(x = day and month, y = measurements, sz = pointsize, c = year)? However, I o not know yet how to split the datetime array into two seperate arrays, I will try to figure that out. Any hint is very welcome of course.
This does what I want:
dt=readtable("Test.xlsx");
d = day(dt.Date,'dayofyear');
m = month(dt.Date);
y = year(dt.Date);
baseyear = min(y);
lastyear = max(y);
cmap = colormap(jet(lastyear-baseyear+1));
G = y - baseyear + 1;
scatter(d,dt.NO2,[],y)
xlim([-.5 365.5])
xticks([0 31 59 90 120 151 181 212 243 273 304 334])
xticklabels({'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'})
ylim([0 5])
hold on
nG = max(G);
L = gobjects(1, nG);
for K = 1 : nG;
L(K) = plot(nan, nan, 'color', cmap(K,:));
end
hold off
title ("")
xlabel ("Months")
ylabel ("uM nitrite")
legend(L, string(baseyear:lastyear))
grid on
box off
Thank you very much for your ideas and support @Walter Roberson!

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products

Release

R2021a

Asked:

on 5 Jan 2022

Commented:

on 6 Jan 2022

Community Treasure Hunt

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

Start Hunting!