user1285419
user1285419

Reputation: 2225

how to get vertical gradient fill in matlab plot

I have a function y=x^2 to plot and I would like to fill the area bound by this curve with gradient color from black to red along the y direction. I found the color online

x = linspace(-3, 3, 20)';
f = x.^2;
M = f.^2;

N = length(x);
verts = [x(:), f(:)-max(f); x(:) zeros(N,1)];

q = (1:N-1)';
faces = [q, q+1, q+N+1, q+N];
p = patch('Faces', faces, 'Vertices', verts, 'FaceVertexCData', [M(:); M(:)], 'FaceColor', 'interp', 'EdgeColor', 'none')

This code show me the area bound with the curve to the xaxis, like

enter image description here

But what I want to fill is the WHITE area. So I modify the code as follows

x = linspace(-3, 3, 20)';
f = x.^2;
M = f.^2;

N = length(x);
verts = [x(:), f(:)-max(f); x(:) zeros(N,1)];

q = (1:N-1)';
faces = [q, q+1, q+N+1, q+N];
p = patch('Faces', faces, 'Vertices', verts, 'FaceVertexCData', [M(:); M(:)], 'FaceColor', 'interp', 'EdgeColor', 'none')

this gives me something like the following enter image description here

it fill the right area but two issues:

  1. the whole image shifted to negative y axis by 9 units
  2. the gradient color was fill from left to right but I want it to fill from bottom to top (vertically)
  3. the colormap was not defined as black to red (I can change that manually though)

Upvotes: 0

Views: 5586

Answers (2)

Floris
Floris

Reputation: 46415

There is a possibly much easier way to achieve almost the same thing... draw the picture as follows:

cplot = repmat(1:256, [256 1])';    % create a 256 square horizontal gradient
xv = linspace(-3, 3, 256);          % range of x values
yv = linspace(0, 9, 256);           % range of y values
cplot(repmat(xv.^2, [256 1])>repmat(yv', [1 256]))=255; % set area below the curve to white
figure
imagesc(xv, yv, cplot);

Now all you have to do is fix the color scale... you will want the color 255 to be white...

Upvotes: 0

Floris
Floris

Reputation: 46415

The vertical shift happened because of the line

verts = [x(:), f(:)-max(f); x(:) zeros(N,1)];

where f(:) - max(f) is always <=0 . I think you just need to use f(:) to solve that problem.

As for the direction of the shading, since you are defining your patches as vertical strips, they will be colored as vertical strips. If you want horizontal shading, you need to define horizontal patches. Can you figure that out, or do you need help?

EDIT - this code does what you are asking:

figure;
x=linspace(-3, 3, 200);
f = x.^2;
plot(x, f, 'r'); hold on % you could leave this line out... then there is no curve
N = numel(x);
for ii = ceil(N/2):N-1
    ix = [ii ii+1 N-ii N-ii+1];
    disp(ix)
    patch(x(ix), f(ix), f(ii)*256/max(f(:)),'edgecolor', 'none');
end

Here is the output: shading example

One more problem - you are defining the color M as f.^2 - isn't that one round of squaring too many? I think you meant it to be x.^2 (or just F)?

Upvotes: 1

Related Questions