How do I shade plot area with increasing and decreasing shades of a color

5 views (last 30 days)
Hello,
I want to plot an area of a graph (x = 1:24, y = -1:1) with one color (black), which I then want to decrease/increase in shading in terms of the time of day. So, that I have a plot which is 'dark' in the background at night and 'light' during the day with x being hours of day and y being a value. My sunrise would be at 6.8 and my sunset would be at 22. I would then overlay scatter plots with data on top.
Can someone please help me? I have tried messing around with patch and area but with no luck

Answers (2)

Samayochita
Samayochita on 24 Mar 2025
Edited: Samayochita on 2 Apr 2025 at 5:07
Hi Michael,
I understand that you are trying to create a scatter plot with gradient background that mimics the natural daylight changes. The sunset happens at “x = 22" and the sunrise happens at “x = 6.8”. You could achieve this by following the steps below:
  • Create a gradient using intensity values (0=black, 1=white) that gradually increase/decrease.
intensity = zeros(size(x));
  • Loop through X-axis values (Time of Day), assign shading based on time.
for i = 1:length(x)
if x(i) < sunrise_start
intensity(i) = 0; % Night (Black)
elseif x(i) < sunrise_end
% Very gradual transition to light grey
intensity(i) = (x(i) - sunrise_start) / (sunrise_end - sunrise_start) * 0.7;
elseif x(i) < midday_start
% Smooth transition to full white
intensity(i) = 0.7 + (x(i) - sunrise_end) / (midday_start - sunrise_end) * 0.3;
elseif x(i) < midday_end
intensity(i) = 1; % Fully bright (White)
elseif x(i) < sunset_start
% Start dimming slowly (stay bright longer)
intensity(i) = 1 - (x(i) - midday_end) / (sunset_start - midday_end) * 0.2;
elseif x(i) < sunset_end
% Gradual fade into darkness
intensity(i) = 0.8 - (x(i) - sunset_start) / (sunset_end - sunset_start) * 0.8;
else
intensity(i) = 0; % Night (Black)
end
end
  • Create the shaded background using the “fill()” function to shade each time step smoothly.
(To know more about fill function, please refer to the following documentation https://www.mathworks.com/help/matlab/ref/fill.html)
% Create the shaded background
hold on;
for i = 1:length(x)-1
fill([x(i) x(i+1) x(i+1) x(i)], [y_limits(1) y_limits(1) y_limits(2) y_limits(2)], ...
[intensity(i) intensity(i) intensity(i)], 'EdgeColor', 'none');
end
  • Overlay the scatter plot on top of the background.
scatter(1:24, rand(1,24) * 2 - 1, 50, 'r', 'filled');
I hope this was helpful.

DGM
DGM on 24 Mar 2025
This is a much more simplistic example, but the main objective here is to simply demonstrate the use of a colorstripe to fill a rectangular area without needing to figure out how to build a complicated fill() or patch() object.
% our expected plot domain and range
xl = [1 24];
yl = [-1 1];
% some fake data
n = 100;
x = diff(xl)*rand(n,1) + xl(1);
y = diff(yl)*rand(n,1) + yl(1);
% generate a cyclic color table
maplen = 256;
t = cos(linspace(0,2*pi,maplen)); % a sinusoidal trajectory
cx = 0.5*sign(t).*abs(t).^0.6 + 0.5; % make it steeper and fit it in [0 1]
CT0 = [1 1 0.5; 0.1 0 0.3]; % the base colors for [day night]
CT = interp1([0 1],CT0,cx); % interpolate along the given trajectory
% permute the color table to form a 1x256x3 image
bgimg = permute(CT,[3 1 2]);
% display the image first, fitting it to the expected area
image(xl,yl,bgimg); hold on
% plot the data atop it
scatter(x,y);
xlim(xl)
ylim(yl)
Again, this is simplistic. I've made no effort to accomodate specific sunrise or sunset times. In this example, all that would be needed is to change cx to any other cyclic curve which spans the unit interval.
Note that by using an RGB color stripe, we leave the axes colormap free to be dictated by the needs of other objects.

Community Treasure Hunt

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

Start Hunting!