This code gives me a strange plot I cannot figure why. Many thanks for any help

figure(2);
start=floor(TrajX(1));
stop=floor(TrajX(length(TrajX)));
P3_FzInv = flip(P3_Fz*-1);
subplot(2,1,1); % top plot, P3Fz v. T4T3
[ax,z1,z2]=plotyy(t(start:stop),z1(start:stop),(start:stop),z2(start:stop));
axis('square');
grid on;
set(z1,'LineWidth',2);
set(z2,'LineWidth',2);
xlabel(ax(1),'seconds');
ylabel(ax(1),'Fz <<--- Power Site --->> P3');
ylabel(ax(2),'T3 <<--- Power Site --->> T4');
hold on;
FigHandle = figure(2);
set(FigHandle, 'Position', [100, 100, 1049, 895])

3 Comments

I just inserted t(start:stop)before variable z2 but still got the same result
Well, we certainly can't tell what might be "strange" with no description whatsoever of what you see or expect and no data with which to recreate it.
At a minimum you'll have to attach the figure and comment upon it; better would be to make a runnable sample including some data that illustrates the problem.
I did attach a figure, but apparently it came unattached. here it is again

Sign in to comment.

 Accepted Answer

" I was unable to get this subplot axis problem fixed"
Don't know why it didn't register with me before, but the problem is
axis('square')
That's changing the axes shape only for the one, last, active axes object and there are two owing to plotyy
The solution is
h1=subplot(2,1,1);
hAx=plotyy(....
axis(hAx,'square')
which will fixup both. The obvious problem is that the one is so short compared to the other; I let the missing t sidetrack (albeit it was a problem in the original post that would lead to confusing plot as well).
My previous example expanded results in --
from
>> subplot(2,1,1)
>> hAx1=plotyy(1:10,rand(1,10),1:10,10*rand(1,10));
>> axis square
>> subplot(2,1,2)
>> hAx2=plotyy(1:10,rand(1,10),1:10,10*rand(1,10));
>> axis(hAx2,'square')
Note don't even need the subplot axes handles (altho it can't hurt to be specific); just must modify both plotyy axes to keep them in synchronicity. linkaxes might help here altho not sure that it will set the 'position' property; didn't test that.

2 Comments

All this turns out to be a lot trickier than I expected. However, the subplot plotyy problem seems to successfully confine the plots to a single square-axis figure. If I can get the RH y-axis T3 and T4)labeled and scaled that would be great. Presently used code is below and figure is attached Many many thanks.
figure(2);
start=floor(TrajX(1));
stop=floor(TrajX(length(TrajX)));
P3_FzInv = flipud(P3_Fz*-1);
z3 = P3_FzInv;
subplot(2,1,1);
hAx1=plotyy(t,z3,t,z2);% zi = P3-Fz as received Z3 = P3_FzInverse
axis square;
subplot(2,1,1)
hAx2=plot(t,z3,t,z2);
axis square;
grid on;
set(hAx2,'LineWidth',2);
xlabel(hAx1(1),'seconds');
ylabel(hAx1(1),'Fz <<--- Power Site --->> P3');
%ylabel(hAx1(2),'T3 <<--- Power Site --->> T4');
title(File2VarTitle);
FigHandle2 = figure(2);
set(FigHandle2, 'Position', [200, 200, 800,800])
subplot(2,1,1);
hAx1=plotyy(t,z3,t,z2);
axis square;
subplot(2,1,1)
hAx2=plot(t,z3,t,z2);
axis square;
What are you doing???!!! You create the subplot, then plot into it with plotyy and again do what I just demonstrated to NOT do -- use the command form of axis without the two axes handles. That's what got you in trouble the first time. Then you do it over again.
What do you want in the plot? The above puts two plots in the upper two of the two subplots created, but the second one writes over the first.
Did you mean
subplot(2,1,1);
hAx1=plotyy(t,z3,t,z2);
axis(hAx1,'square')
% rest of stuff for top plot goes here
...
% followed by
hAx2=subplot(2,1,2); % NB: the trailing '2'
hL2=plot(t,z3,t,z2); % NB: plot() returns line handles, not axes
axis square % Can get away here as *plot is only is one axis
grid on;
% finish up on the lower plot here
...
instead, mayhaps?
It's really not that complicated; the only tricky part() is that there are two axes for *plotyy and so you have to do the same thing to each of them. That's what I demonstrated before that when applied the command form of axis to the upper plot that gives you the two with differing aspect ratios whereas the bottom did both by use the function form of axis with the proper axis handles.
Also, as noted in the comment, plot returns (an array of) line handle(s), not axes handles. Hence you really should keep the handle returned by subplot for further manipulations on it should be desired altho you can use the subplot function in its referencing form rather than creating one.
() The only reason this thread turned out so long is that (as sometimes happens) Walter and I both missed the fundamental issue initially and went down a fruitless path. *axis square isn't used a lot so it just didn't register for either of us until later on it finally dawned on me what caused the symptom your first attached plot showed.
After that, it was straightforward application of the functional form for it that accepts the axes handles so operate on both simultaneously to keep them in synch. That's what my revised example demonstrated; the first, top, subplot is deliberately wrong to illustrate the problem whereas the lower is correct for using plotyy and the 'square' aspect ratio. When using plot instead of plotyy then, as documented --
  1. There's only a single axis for the lines to be plotted into, and
  2. It (PLOT, that is) returns line handles instead of axes handles.
ADDENDUM
I earlier mentioned linkaxes as perhaps letting you "get away with" less explicit effort in the actual modifications to the x-axes. Just out of curiosity I did the 'spearmint -- as I had surmised it doesn't solve the aspect ratio problem. That is,
subplot(2,1,1)
hAx=plotyy(...
linkaxes(hAx,'x')
axis square
leaves you with the one axes square, the other default as I surmised would likely be so.

Sign in to comment.

More Answers (4)

plotyy() works by creating a second axes, and so it is not compatible with using subplot(). subplot() works by creating axes to plot into, not by subdividing the figure into sections.
You can pass an axes or axes pair into subplot(); see http://www.mathworks.com/help/matlab/ref/plotyy.html . Notice though that even if you pass an axes pair, it will only pay attention to the first of the two axes and will generate its own axes for the second plot.
Work around:
ax1 = subplot(2,1,1);
[ax,p1,p2] = plotyy(ax1, t(start:stop),z1(start:stop),t(start:stop),z2(start:stop));
set(ax(2), 'Position', get(ax(1), 'Position'))

7 Comments

ax1=subplot(2,1,1); % top plot, P3Fz v. T4T3
[ax,h3,h2]=plotyy(t(start:stop),z3(start:stop),t(start:stop),z2(start:stop));
get(ax(1),'Position');
set(ax(2), 'Position', get(ax(1), 'Position'));
xlim([start,stop]);
I very much appreciate your patience. Here's what I did (code & figure), with and without the "get(ax(1),'Position');" line; thinking maybe to get before set. but...sadly...no effect. Maybe I should just abandon the subplot idea
[ax,h3,h2]=plotyy(t(start:stop),z3(start:stop),t(start:stop),z2(start:stop));
That's not quite what Walter suggestd, Don. He used
[ax,h3,h2]=plotyy(ax1,t(start:stop),z3(start:stop), ...
t(start:stop),z2(start:stop));
where ax1 is the handle of the axes from the subplot call.
I did the following here and didn't see any issue w/ the size of the axes...
>> ax1=subplot(2,1,1);
>> hAx=plotyy(ax1,1:10,rand(1,10),1:10,10*rand(1,10));
Thnx X 10^6 for your patience and help Ultimately, I was unable to get this subplot axis problem fixed, so I went to plots of two individual figures. That works and I can move on. BUT where can I find the place to vote for helpful answers? Ive seen it before but cannot locate now
You can Vote by looking for the ‘Thumbs up’ icon just under Walter’s raccoon picture.
Nyctereutes procyonoides viverrinus ("Tanuki", "Japanese Racoon-dog") artistic representation to be more accurate. It is a Canidae (canine), as opposed to racoons which are Procyonidae.
Ornithorhynchus anatinus sends thanks to Nyctereutes procyonoides viverrinus We're gaining on it!

Sign in to comment.

I noticed the following this AM I missed yesterday --
You're missing the t variable for the x-vector on the RH axes in the plotyy call so that'll plot versus the indices array instead of t. That will, indeed, "look funny"
as you can see in the top plot, one of the variables (z2, I think) does not fit within the plot boundaries I can't find a problem with the plotyy code. maybe this is a bug. If so, can you suggest a work-around?
many thanks for help

1 Comment

Here's the code. t (=x-vector)added to (start:stop) in plotyy call, RH axes. still have problem with variable z2 (RH axes % code figure(2);
start=floor(TrajX(1));
stop=floor(TrajX(length(TrajX)));
P3_FzInv = flipud(P3_Fz*-1);
z3 = P3_FzInv;
subplot(2,1,1); % top plot, P3Fz v. T4T3
[ax,p1,p2]=plotyy(t(start:stop),z1(start:stop),t(start:stop),z2(start:stop));
xlim([start,stop]);
axis('square');
grid on;
set(p1,'LineWidth',2);
set(p2,'LineWidth',2);
xlabel(ax(1),'seconds');
ylabel(ax(1),'Fz <<--- Power Site --->> P3');
ylabel(ax(2),'T3 <<--- Power Site --->> T4');
hold on;
FigHandle = figure(2);
set(FigHandle, 'Position', [100, 100, 1049, 895])
NOTE: "Fig 2 with t for RH axes" shows as "attached" but I cannot get it to appear in this comment window
Problem still persists with z2 not confined to plot box Is this a bug in the plotyy code?

Sign in to comment.

In the words of Colombo, "one more thing..."
plot looks correct (finally!) I have tried all the combinations I can think of but still cannot get lineWidth set to 2. I would study the principles behind this plotyy design with handles, if I could locate a book that explains the subject. Otherwise, otherwise its trial and error, then ask a (probably) elementary question. Many thanks, as usual, for any assistance

5 Comments

Really belongs as another comment to the previous answer rather than an Answer itself, but that aside, it's only that it kinda' breaks up the ordering.
What need is to see the actual code that you used to create the final version to see what you did, precisely, as noted in previous comment the code you posted couldn't have generated that attached plot and we don't know what variables you used or saved.
But, presuming from the above image it's the two lines in the upper subplot you're speaking of, then you needed to have saved the line handles as well as the axes handles from the plotyy call(*) to make changes most simply to the drawn lines; you can always go "handle-diving" and retrieve whatever is in the figure/axis of question but there's rarely a need if you keep the info while building the plot.
That would mean the plotyy call would look something like
[hAx1,hL1,hL2]=plotyy(....
Since you only drew a line on each of the two axes (as opposed to mixture of, say, bar patches and lines or other objects) and you want a constant new width on them, it's only an additional call
set([hL1 hL2],'linewidth',2)
Done! There are methods for later releases than R2012b that don't use set but I don't believe they handle the vector of handles form.
As for the "How To", the plotyy doc says
[AX,H1,H2] = plotyy(...) returns the handles of the two axes created in AX and
the handles of the graphics objects from each plot in H1 and H2.
AX(1) is the left axes and AX(2) is the right axes.
This is really all the information you need from plotyy; everything else follows from the general behavior of handle graphics which, admittedly, is a large subject with which to become familiar. One simply has to invest some time in learning how HG works as a cost of becoming more adept with Matlab.
The first thing in thinking of how to go about making modifications is the consideration of which properties belong to which objects. In this case, it should be clear (I'd hope) that the line width will be a property of the drawn lines, not that of the parent axis. That and perhaps even more obviously that you used plot should give you the clue to go look at what plot documentation says and that the return value is
h = plot(...) returns a column vector of handles to lineseries objects,
one handle per line.
which gives you the information that the plotyy call does need the optional additional return values for you to use later. Hopefully that gives you kind of a road map for how to think through the process that will help going forward.
Optionally, there's the "trick" of using an anonymous function whose handle can be passed to plotyy but that holds the additional information of other properties you'd like to set but can't pass via the expanded argument list facility of plot.
() And, to be completely clear, the "line handles" referred to aren't really the outputs of *plotyy itself; it is just a wrapper around the two plotting routines ( plot by default, others by passing explicitly) which actually do the work after plotyy creates the two axes. Consequently what the two alternate returns contain is dependent entirely on what those functions themselves return. Hence, also, that the documentation for plotyy cannot contain the information on what is contained in those return values for any given call; it depends on the invocation as to which routines are used and so the earlier comment of having to follow the trail of bread crumbs to, in this case, plot (but it could've been bar or any other 2D routine).
ADDENDUM
One more refinement to your plot I'd suggest (and take the opportunity yet again to nag TMW about not having fixed it even yet after, like, 30 years! :( ) -- note the tick labels don't have the same precision for the integer values and that just looks tacky. It's pretty simple to fix, albeit it shouldn't be necessary if TMW would just clean up their act:
For the upper subplot presuming the axes handle array is hAx1
yt=get(hAx1,'ytick'); % return tick values y-axes; will be cell array
set(hAx1,{'yticklabel'},{cellfun(@(y) num2str(y.','%0.1f'),yt,'uniform',0)})
For the lower since there's only the one axes, same idea except don't have a cell array, only a simple one--
yt=get(hAx2,'ytick'); % subplot(2,1,2) ytick values
set(hAx2,'yticklabel',num2str(yt.','%0.1f'))
NB: I used hAx2 for the lower handle, obviously use whatever you used for the variable name in your code. These details are why it would help to post your actual code...
The upper subplot example I gave before now looks as below after the fixup--isn't that much nicer???? :) Again, why, oh why, TMW can't you do this internally???!!!
Note also that if one wants to eliminate the temporary array yt one can fold the get into the set...
set(hAx1,{'yticklabel'}, ...
{cellfun(@(y) num2str(y.','%0.1f'),get(hAx1,'ytick'),'uniform',0)})
One starts writing (and testing) stuff like this from the inside out, getting the first steps right then encapsulating them into the next higher-level step.
It works now! I don't completely understand why, but..THANKS!!!
subplot(2,1,1);
[hAx1,hL1] =plotyy(t(start:stop),z1(start:stop),t(start:stop),z2(start:stop));
% zi = P3-Fz as received Z3 = P3_FzInverse
% z2 = T4_T3 as received z4= T4_T3Inverse
set(hL1,'LineWidth',2);
axis square;
[hAx2,hL3,hL2] =plotyy(t(start:stop),z1(start:stop),t(start:stop),z2(start:stop));
set(hL2,'LineWidth',2);
set(hL3,'LineWidth',2);
grid on;
xlabel(hAx1(1),'seconds');
ylabel(hAx1(1),'Fz <<--- Power Site --->> P3');
ylabel(hAx2(2),'T3 <<--- Power Site --->> T4');
title(File2VarTitle);
FigHandle2 = figure(2);
set(FigHandle2, 'Position', [200, 200, 800,800])
I don't see how you could possibly have gotten the attached figure from the above code again...at a bare minimum there are only two ylabel calls and there are three labels on the figure.
It doesn't seem that you're paying any real attention to the code and help you're being given. Again, you've still got the first subplot call followed by two successive plotyy calls, the first of which again is followed by the command form of the axis square command so that'll have screwed up the aspect ratio yet again, as well as not having saved the second set of line handles. The second plotyy call is identically the same data and will consequently overwrite the first. I don't know what the second figure is; you don't show code that would have generated it at all.
The result of the first series up through axis square is similar to the following plot excepting for the random data here instead of yours.
on which you'll note only one axis ratio changed and also only one line width has been changed since you only saved the one handle array, not both sets. The second plotyy overwrites the first LH axes since the positions are not the same after having changed the aspect ratio but deletes the second with identically the same position values, thereby destroying the first RH axes hAx1(2). To see this,
>> subplot(2,1,1)
>> [hAx1,hL1]=plotyy(0:10,rand(1,11),0:10,10*rand(1,11));
>> axis square
>> gca % which is left as current axis?
ans =
173.0385
>> hAx1 % first plotyy axes handles
hAx1 =
173.0385 175.0385
>> % Now introduce second PLOTYY() call...
>> [hAx2,hL3,hL2]=plotyy(0:10,rand(1,11),0:10,10*rand(1,11));
>> hAx2 % and second plotyy axes handles
hAx2 =
173.0385 175.0386
>>
Note that the first (LH) axis is same handle, RH isn't and in fact the RH axes from the first plotyy call has been destroyed...the second is no longer valid as shown
>> ishandle(hAx1)
ans =
1 0
>>
The sequence as I've outlined before should look something like --
subplot(2,1,1)
[hAx1,hL1,hL2]=plotyy(... % top two-line plot here...
set([hL1 hL2],'linewidth',2) % fixup linewidths
% put rest of annotation, labels, etc, here on hAx1(1), hAx1(2)
....
% lower half (square) plot...
hAx2=subplot(2,1,2) % create lower axes, save handle
hL=plot(... % data for the square axes
set(hL,'linewidth',2)
axis(hAx2,'square')
% rest of labelling, etc., goes here
...
It's really not complicated...
As a note, for the lower plot since you're not using plotyy you can simplify a little further using the ability of plot for named parameter pairs...
% lower half (square) plot...
hAx2=subplot(2,1,2) % create lower axes, save handle
hL=plot(... ,'linewidth',2); % can set the style/width, etc.
axis(hAx2,'square')
% rest of labelling, etc., goes here
...
Hopefully it makes more sense now and that it isn't any deep mystery any longer but a logical sequence of steps.
It wouldn't have been difficult at all if either Walter or I had recognized the first go-'round the issue was entirely owing to axis and the multiple handles and not thrown in the red-herring of which set of axes were plotting into. It's documented behavior in subplot regarding the destruction of axes that are overlaid by the creation of new one(s) that overlay their position while an exact position match makes that existing axes the new target; hence the behavior illustrated above with the two successive plotyy calls of still ending up with only two valid handles out of the four which had been "created".

Sign in to comment.

Categories

Asked:

Don
on 14 Jan 2016

Commented:

dpb
on 21 Jan 2016

Community Treasure Hunt

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

Start Hunting!