MATLAB Answers

Change bar colors based on date

1 view (last 30 days)
Jenny
Jenny on 4 Dec 2019
Commented: Adam Danz on 10 Dec 2019
Hi. I am plotting a bar chart for each month showing the maximum tidal height for that day. I would like to color each phase of the moon with its own color for each month of the year. For example, full moon on 10. jan = green bar, new moon on 24. jan = red bar. first quarter on 3. jan = brown bar and last quarter on 17. jan = orange bar (see first fig below).
The data is read in from an excel fil from the "edited data and charts" tab (see attached excel file).
The code I have generated plots the tidal heights for each month but not with specified colors for specified bars (see second fig below).
January2020.png
TidalHeights2020.png
Question 1: How can I specify the color for the bars based on the date of the phase of the moon? The dates can be read in from the excel fil from the "Moon phases" tab.
Question 2: My title goes over two lines instead of one line. How can I force the title to be on one line? i.e. the year next to the month.
%% Setup the Import Options
opts = spreadsheetImportOptions("NumVariables", 2);
% Specify sheet and range
opts.Sheet = "Edited data and charts";
opts.DataRange = "D2:E367";
% Specify column names and types
opts.VariableNames = ["Date", "HighWater"];
opts.VariableTypes = ["datetime", "double"];
% Import the data
Tides2020 = readtable("Tidal Predic 2020\Tides2020_KSU.xlsx", opts, "UseExcel", false);
%% Clear temporary variables
clear opts
%%
Data=Tides2020.HighWater;
Date=Tides2020.Date;
%Days=[31 28 31 30 31 30 31 31 30 31 30 31];
Days=[31 29 31 30 31 30 31 31 30 31 30 31];
Arstall=2020;
Months={'januar' 'februar' 'mars' 'april' 'mai' 'juni' 'juli' 'august' 'september' 'oktober' 'november' 'desember'};
Start=1;
End=Days(1);
Month=Months(1);
figure1=figure
for i=1:12
subplot(6,2,i)
h=bar(Data(Start:End),'stacked');
%h.FaceColor = 'flat';
title([Months(i) num2str(Arstall)]);
%xlabel('Dag');
xticks([1:1:End]);
xlim([0.3 Days(i)+0.7]);
ylim([140 270])
set(gca,'YTickLabel',[]);
yticks([140:20:270]);
Start=End+1;
if End <366 % change to 366 for leapyear
End=End+Days(i+1);
end
end

  0 Comments

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 4 Dec 2019
Edited: Adam Danz on 10 Dec 2019
The only place in your data where I see moon phase is in column F of your spreadsheet and only the first month is indicated. There are lots of ways to denote the moon phase. This solution assumes that column F will contain this information for each month where each row in F will be one of the following:
  • first quarter
  • full moon
  • last quarter
  • new moon
All other rows will be ignored. Extra white space and case (upper/lower) will be ignored but if there are typos then the code will miss a phase. It would be very easy to change how you're denoting moon phase but I went with this since it's what I saw in your file.
Step 1: Read column F
You'll need to add column F to the data you're reading in
opts = spreadsheetImportOptions("NumVariables", 3);
% Specify sheet and range
opts.Sheet = "Edited data and charts";
opts.DataRange = "D2:F367";
% Specify column names and types
opts.VariableNames = ["Date", "HighWater","MoonPhase"];
opts.VariableTypes = ["datetime", "double","char"];
% Import the data
Tides2020 = readtable("Tides2020_KSU.xlsx", opts, "UseExcel", false); % *** I REMOVED THE PATH, YOU CAN ADD IT BACK IN
Step 2: get moon phase code and choose color
Here I add a new column to the Tides2020 data: MoonCode which is a value 1:4 or NaN. See inline comments below. If you decide to use a different indicator in column F of your spreadsheet, you'll need to make changes here.
% Get moon phase code
% 1 = first quarter, 2=full, 3=last quarter, 4=new, NaN = none of the above
Tides2020.MoonCode = nan(size(Tides2020.MoonPhase));
Tides2020.MoonCode(strcmpi('first quarter', strtrim(Tides2020.MoonPhase))) = 1;
Tides2020.MoonCode(strcmpi('full moon', strtrim(Tides2020.MoonPhase))) = 2;
Tides2020.MoonCode(strcmpi('last quarter', strtrim(Tides2020.MoonPhase))) = 3;
Tides2020.MoonCode(strcmpi('new moon', strtrim(Tides2020.MoonPhase))) = 4;
Now choose what color will be used for each of the phase (of course you can change the colors).
% Colors in order of moon phases 1:4
moonPhaseColor = [
0.85938 0.078125 0.23438; %Crimson
0.0 0.5 0.0 ; %Green
0.64453 0.16406 0.16406; %Brown
1.0 0.64453 0.0 ]; %Orange
Step 3: Set colored bars indicating moon phase
There are a few ways to do this but the main idea is that you must create separate objects for each bar-color. The easiest and cleanest way to do that in this case (IMO) is to just overlay the colored bars on top of the other bars. This goes within your i-loop.
for i=1:12
subplot(6,2,i)
h=bar(Data(Start:End),'stacked');
% |_ why? _|
% Loop through each moon phase % % % %
hold on %
for m = 1:4 %
% get index of moon phase % ADD
tempX = h.XData(Tides2020.MoonCode(Start:End) == m); % THIS
tempY = h.YData(Tides2020.MoonCode(Start:End) == m); % SECTION
tempH = bar(tempX,tempY); %
tempH.FaceColor = moonPhaseColor(m,:); %
end %
% % % %
Why are you using 'stacked' bars when you only have 1 column of data? You could removed 'stacked' and get the same results.
Since your excel file only contains moon phase data for 1 month, only January will contain the colored bars until you add the rest of the moon phases in column F of the spreadsheet.
Step 4: Make title 1 line
Here are two ways to solve this:
% Option 1 (recommended)
title(sprintf('%s %d', Months{i}, Arstall))
% Option 2
title([Months{i}, ' ', num2str(Arstall)]);
% Note ^ ^ curly brackets (you were using parentheses)

  2 Comments

Jenny
Jenny on 10 Dec 2019
Thanks Adam. This worked perfectly.
Adam Danz
Adam Danz on 10 Dec 2019
Glad I could help!

Sign in to comment.

More Answers (0)

Sign in to answer this question.