问题
Create a figure with two y-axes, using yyaxis:
figure
yyaxis left
hl = plot([0 10],[0 10],'-');
yyaxis right
hr = plot([0 10],[10 0],'--');
The following curious behaviour has been found. This has been tested in R2017b and in R2019a on Windows 10.
The objects hl
and hr
seem to belong to the same axis (that is, yyaxis
does not create a new axis):
>> get(hr, 'parent')==get(hl, 'parent')
ans =
logical
1
However, the 'children'
property of the axis only reflects one object:
>> get(get(get(hl, 'parent'), 'children'), 'LineStyle')
ans =
'--'
>> get(get(get(hr, 'parent'), 'children'), 'LineStyle')
ans =
'--'
Also, the YAxisLocation'
property of the parent axis has the same value for both objects:
>> get(get(hl, 'parent'), 'YAxisLocation')
ans =
'right'
>> get(get(hr, 'parent'), 'YAxisLocation')
ans =
'right'
If we now click on the solid line, to make it the current object,
>> get(get(get(gco, 'parent'), 'children'), 'LineStyle')
ans =
'-'
>> get(get(get(hl, 'parent'), 'children'), 'LineStyle')
ans =
'-'
>> get(get(get(hr, 'parent'), 'children'), 'LineStyle')
ans =
'-'
>> get(get(gco, 'parent'), 'YAxisLocation')
ans =
'left'
Similarly, if we now click on the dotted line,
>> get(get(get(gco, 'parent'), 'children'), 'LineStyle')
ans =
'--'
>> get(get(get(hl, 'parent'), 'children'), 'LineStyle')
ans =
'--'
>> get(get(get(hr, 'parent'), 'children'), 'LineStyle')
ans =
'--'
>> get(get(gco, 'parent'), 'YAxisLocation')
ans =
'right'
As a check,
>> get(gcf, 'children')
gives only one axis too, and
>> get(get(gcf, 'children'), 'children')
behaves similarly: only the object that was plotted last, or thas has been made current, is listed.
The above behaviour can be summarized as follows:
- There is only one axis (and the
'parent'
property of all objects refers to that axis, as expected). - The
'children'
property of the axis lists only one object, namely the current object, or the object that was plotted last. - The
'YAxisLocation'
property of the axis dynamically changes between'left'
and'right'
. Again, this is determined by the current object, or the object that was plotted last.
It's not clear how to make sense of this behaviour. The following questions naturally arise:
- Is this documented somewhere?
- How can two objects have the same axis as
'parent'
, but that axis only has the current object as'children'
? - Why does the
'YAxisLocation'
also change depending on which the current object is?
回答1:
To me it looks like yyaxis
does some nasty-behind-the-scenes things and there's lots of hidden data we can't access.
The documentation does say that:
yyaxis left
activates the side of the current axes associated with the left y-axis. Subsequent graphics commands target the left side.
and
The
Children
property of theAxes
object only contains the children for the active side. To access all the children for both sides, use theallchild
function.
Changing the "side" with yyaxis
therefore changes the contents of the Axes
object, I presume that the contents for the other side gets stored in some hidden location that I haven't been able to find. yyaxis
is P-code, so we won't be able to figure out what exactly it is doing.
This is interesting:
figure
yyaxis left
hl = plot([0 10],[0 1],'-');
yyaxis right
hr = plot([0 10],[100 0],'--');
h = gca;
yyaxis left
h.YLim
yyaxis right
h.YLim
The code creates left and right axes with different limits. We get the handle to the axes, change to left, read the limits from the handle, then change to right and read the same property again. The first time it returns [0,1]
, the second time it is [0,100]
. That is, the Axes
object with handle h
changes when we call yyaxis
.
The only indication I've found that h
points to axes with two sides is that h.YAxis
returns two handles to NumericRuler
objects, one for each side.
I can't but feel this is awkward behavior. I would have expected there to be two Axes
objects, both with the same Position
property, and maybe with listeners that keep the two in sync.
来源:https://stackoverflow.com/questions/59760632/behaviour-of-axis-properties-with-yyaxis