setting order and transparency in plotyy

2 次查看(过去 30 天)
[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!

采纳的回答

Walter Roberson
Walter Roberson 2011-11-14
You cannot do that with plotyy.
Transparency requires using the OpenGL renderer; none of the other renderers support it. But the OpenGL renderer is defined in such a way that when you have an area (or surface) and a line in the same plane, the order in which they are drawn does not depend upon the order of the commands: OpenGL reorders them as it sees fit. And unfortunately the drivers for some graphics card exactly reverse the proper order, so you cannot count on it always being the same.
When you are using OpenGL, the mechanism you need to use to ensure that one object is in front of the other is to change the relative Z coordinates of the two objects so that they are no longer in the same plane; OpenGL will then use normal "closer object is on top" rules. In order to do that with a line plot, you will have to use plot3() rather than plot(). I do not know at the moment what would be needed to change the Z coordinates of an area plot.

更多回答(2 个)

Achim Goheer
Achim Goheer 2012-9-5
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 个评论
Walter Roberson
Walter Roberson 2012-9-7
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.
The behavior of OpenGL is documented here
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).

请先登录,再进行评论。


Achim Goheer
Achim Goheer 2012-9-7
编辑:Achim Goheer 2012-9-7
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');
  1 个评论
Zoe Zhang
Zoe Zhang 2012-9-7
Yes, I was only looking for a workaround when I asked this question. But I will keep the code for future reference. This is great, thanks~

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Two y-axis 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by