setting order and transparency in plotyy
Show older comments
[AX,H1,H2] = plotyy(x1,y1,x2,y2,@plot,@area);
So I plot a line and an area in one chart. Sadly, part of my line is covered by the area and cannot be seen... How to use program to force the line in front of the area and make the area transparent? How to set alpha? Thanks!
Accepted Answer
More Answers (2)
Achim Goheer
on 5 Sep 2012
Of course you can do that! Here is a minimal working example (with comments) using 'uistack':
x1=[0, 1];
y1=[1, 0];
x2=[0, 1];
y2=[0, 1];
[AX,H1,H2] = plotyy(x1,y1,x2,y2,@plot,@area);
set(H1, 'LineWidth', 9);
set(H2, 'FaceColor', 'k');
% By default the objects on the right y-axis (in this example the area) are
% drawn on top of the objects on the left y-axis (in this example the line).
% But we want the line on top of the area, so we raise the z-order-value
% of the left y-axis (AX(1)) by 1.
uistack(AX(1));
% Now we have to adjust the backgrounds: By default the left axis (AX(1))
% has a white background and the right axis (AX(2)) has a transparent
% background. Since we changed their z-ordering, we need that to be the
% other way around.
set(AX(1), 'Color', 'none');
set(AX(2), 'Color', 'w');
6 Comments
Oleg Komarov
on 5 Sep 2012
Nice workaround.
Zoe Zhang
on 5 Sep 2012
Walter Roberson
on 5 Sep 2012
No, this does not work reliably in OpenGL, which does not obey uistack() when it comes to mixing lines and surfaces.
Achim Goheer
on 7 Sep 2012
Hi Walter Roberson,
I don't understand your point. Are you trying to say that some graphics card drivers cannot be reliably instructed to draw one object on top of the other? ("...unfortunately the drivers for some graphics card exactly reverse the proper order, so you cannot count on it always being the same.") If that was the case then all programs running on that computer using OpenGL would have that problem.
Do you know of any graphics card that draws the blue line in my example code below the areas, instead of on-top? Send it to me via post mail. I will eat it with fork and knife.
And why should OpenGL obey or not obey uistack()? ("...OpenGL, which does not obey uistack()...") OpenGL is on a lower layer and knows nothing about the code that it is being called by.
Walter Roberson
on 7 Sep 2012
Unfortunately I cannot send you the graphics card I personally observed this on; the card is government property and the regulations about disposal of government property is quite strict.
OpenGL and Zbuffer renderers display objects sorted in front to back order, as seen on the monitor, and lines always draw in front of faces when at the same location on the plane of the monitor. Painters sorts by child order (order specified).
paul harder
on 14 Oct 2014
Worked for me. Thanks!
Achim Goheer
on 7 Sep 2012
Edited: Achim Goheer
on 7 Sep 2012
Hi Zoe,
you also talked about setting alpha values. I think you just meant it as a workaround to get the line visible behind the area. But just in case you are still interested in setting transparency, here is a slightly updated version of the code.
The diagram now contains a black area that appears gray, since it uses alpha=0.6. On top of it you see a green area with alpha=0.8. On top of all you see the (non-transparent) blue line.
As you will notice from the first (gray) area in the diagram, the transparency-setting of the area only applies to its inner filling, not to its edge. The edge is still opaque. So if you feel annoyed by the non-transparent edge of an area (by default 1 pixel wide), you can set the edge to be invisible, as I did with the edge of the second (green) area.
Only setting the transparency of a line seems not possible (except for really heavily working-around).
Here is the code:
x=[0, 1];
y1=[1, 0];
y2=[0, 1];
y3=[.4 .4];
% draw the line on the left axis and the first area on the right axis
[axes, line_1, area_1] = plotyy(x, y1, x, y2, @plot, @area);
% hold the right axis to allow for further drawing without destroying the old
% content
hold(axes(2), 'on');
% add another area on the right axis
area_2 = area(axes(2), x, y3);
% give the line and the areas the desired properties
set(line_1, 'LineWidth', 5); % 5 seems to be the maximum line width
set(line_1, 'Color', 'b'); % make the line blue (should be default anyway)
set(area_1, 'FaceColor', 'k'); % make first area black
set(area_2, 'FaceColor', 'g'); % make second area green
set(area_1, 'LineWidth', 2); % make first area's edge thicker
set(area_1, 'EdgeColor', 'k'); % make first area's edge color black (default)
set(area_2, 'EdgeColor', 'none'); % make second area's edge invisible
set(get(area_1, 'Children'), 'FaceAlpha', .6); % set first area's transparency
set(get(area_2, 'Children'), 'FaceAlpha', .8); % set second area's transparency
% By default the objects on the right y-axis (in this example the areas) are
% drawn on top of the objects on the left y-axis (in this example the line).
% But we want the line on top of the areas, so we raise the z-order-value
% of the left y-axis (axes(1)) by 1.
uistack(axes(1));
% Now we have to adjust the backgrounds: By default the left axis (axes(1))
% has a white background and the right axis (axes(2)) has a transparent
% background. Since we changed their z-ordering, we need that to be the
% other way around.
set(axes(1), 'Color', 'none');
set(axes(2), 'Color', 'w');
%release the right axis
hold(axes(2), 'off');
Categories
Find more on Graphics Performance in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!