fill/patch interpolate alpha

19 views (last 30 days)
Just Manuel
Just Manuel on 6 Apr 2022
Answered: Just Manuel on 19 Apr 2022
Hi
I'm not sure if i'm hitting a limitation of matlab here, or if I'm actually missing something.
What i'm trying to do:
Suppose you have multiple measurement series with mean, max and min for each data point. To get a visual idea where the data lies, I plotted the individual series as patches (limited by min and max) on top of each other with a semitransparent color. This way, the the areas that are covered the most get colored the darkest. So far, so good, that all worked.
What is not working to my expectations:
I'd like to go one step further and plot the areas with a gradient, such that the mean values are dark, while min and max fade to full transparency. I have fiddeled with both the fill and patch functions (what's the difference between them anyway?), but have only succeeded in fading the color to white and setting an uniform alpha for the whole area. While this looks fine for a single measurement series, the white edges are visible when they crosss another series. This works against the readability of the whole thing.
Example
I have coded up a small example to visualize my problem. If you use the function "flat", you get the result without gradient, which is close to what i'm trying to achieve (the top two curves in the plot). If you use the function "withGradient", you can see the white edges of the top curve (the bottom two curves in the plot).
color = [0.2, 0.1, 0.5];
spread = 0.1;
x = 0:100;
flat(x, 0.8 + sin(x ./ 16), spread, color);
flat(x, 1.3 - 0.01 * x, spread, color);
withGradient(x, -0.8 + sin(x ./ 16), spread, color);
withGradient(x, -0.3 - 0.01 * x, spread, color);
function flat(x, y, spread, color)
len = length(x);
% generate vertices
xx = [x, flip(x)]';
yy = [y + spread, flip(y - spread)]';
S.Vertices = [xx, yy];
% generate faces
S.Faces = 1:2*len;
% styling
S.FaceColor = color;
S.FaceAlpha = 0.5;
S.LineStyle = 'none';
% draw patch
patch(S);
end
function withGradient(x, y, spread, color)
len = length(x);
% generate vertices
xx = [x, flip(x), x]';
yy = [y + spread, flip(y), y - spread]';
S.Vertices = [xx, yy];
% generate faces
S.Faces = [1:2*len; len+1:3*len];
% generate color values
S.FaceVertexCData = 1 - ((1:3*len > len & 1:3*len <= 2*len)' * (1 - color));
% styling
S.FaceColor = 'interp';
S.FaceAlpha = 0.5;
S.LineStyle = 'none';
% draw patch
patch(S);
end
What was the question again?
Is there a way to have the opacity (alpha) interpolated from mean to min/max respectively?
Cheers
Manuel

Accepted Answer

Just Manuel
Just Manuel on 19 Apr 2022
Oh well... it turned out I acutually was missing something... for patch, it is even documented:
You can specify another array FaceVertexAlphaData, then you have to set FaceAlpha to 'interp' and voilà, everything works as expected :D

More Answers (1)

Frantisek Gaspar
Frantisek Gaspar on 13 Apr 2022
  1 Comment
Just Manuel
Just Manuel on 19 Apr 2022
Thanks Gaspar!
I have read that article and experimented around a bit. Unfortunately, it does not solve my problem:
While the undocumented method allows to interpolate colors from point to point along an edge of a line, my goal is to interpolate colors from point to point across a patch.
While I succeeded to make a Nx4 array for the CData (FaceVertexCData respectively), it will not accept that data: "Value must be an Nx1 or Nx3 array of numeric type".
I could try generating the patch myself using pieces of lines with masking of some kind, but I guess that'd be too much effort :)

Sign in to comment.

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!