I have an issue with changing the plotting order when I am plotting on two different y-axes. I want the plot on the left axis to be infront of the plot on the right yaxis. I already treid to change the order of calling the plotting functions, as you can see below. Further, I looked into this post:
Similar StackOverflow Question
But the accepted answer did not help me. I guess the issue is that I only change the order on one axis.. Also the command uistack only results in an error for I guess the same reason. Any help is highly appreciated.
My code:
V = horzcat((-2:0.1:2), (2:-0.1:-2));
t = (0:0.01234568:1.01);
T = (0:25:2025);
figure(30);
yyaxis right
plot(t ,V, 'Linewidth',3); hold all;
xlabel('Time / s');ylabel('Voltage / V');
set(gca,'FontSize',fontsize, 'LineWidth',2,'TickLength',[0.025 0.025])
xticks([0., 0.25, 0.5, 0.75, 1]);
ylim([-2, 2]),
ax = gca;
ax.XAxis.MinorTick = 'on';
ax.XAxis.MinorTickValues = (0:0.05:1);
set(ax.YAxis, 'MinorTick', 'on')
set(ax.YAxis, 'MinorTickValues', (-2:0.25:2))
yyaxis left
top = plot(t ,T, 'Linewidth',3); hold all;
xlabel('Time / s');ylabel('Temperature / K');
ax = gca;
%ax.YAxis.MinorTick = 'on';
%ax.YAxis.MinorTickValues = (250:50:650);
set(ax.YAxis, 'MinorTick', 'on')
set(ax.YAxis, 'MinorTickValues', (250:50:650))
chH = get(gca,'Children');
set(gca,'Children',[chH(end);chH(1:end-1)]);
uistack(top, 'top');
What it looks like now:
As you can see the orange line is in front of the blue one, however I would like to have it the other way around.
Any help is highly appreciated.
That's because the get(gca,'Children') returns only one line object! And it is the blue one. So this code actually does nothing.
But I believe the problem comes from the yyaxis method. According to MATLAB docs:
Tips
...
The Children property of the Axes object only contains the children for the active side. To access all the children for both sides, use the allchild function.
Axes Properties
Axes properties related to the y-axis have two values. However, MATLABĀ® gives access only the value for the active side. For example, if the left side is active, then the YLim property of the Axes object contains the limits for the left y-axis. However, if the right side is active, then the YLim property contains the limits for the right y-axis.
What I get from above description is that when you call yyaxis, another axes object is created an placed above the original one. But they are somehow internally coupled, so you can access their properties, including their separated lists of children, by activating them after calling yyaxis again.
Related
I am using pzmap to plot system poles and zeros for different values of L. But the plot has additional YTick Labels at the right side which I cannot see in the axes properties. Also, I do not have the handle corresponding to constant damping gridlines whose color and properties I would like to change.
MWE
clear;clc
cb=parula(10);
s=tf('s');
L_array=5:5:50;
figure; hold on;
for i=1:length(L_array)
L=L_array(i);
G=((58.2+11.7*L)*s^2*25^2+(3996.8 + 815.7*L)*s*25+815.7*25^2)/(s^2*(s^2*25^2+126.9*s*25+(3996.8+1.9*25^2)));
CL=feedback(G,1);
pzmap(CL);
end
h = findobj(gca,'type','line');
for jj=2:length(h)
set(h(jj),'MarkerSize',12,'Color',cb(floor(jj/2),:));
end
grid;
colormap(parula);
c=colorbar;
Also the colorbar is inverted i.e. Blue corresponds to larger L and vice versa. I would like to have it inverted! Thanks in advance!
I could not find any handle to the desired objects in the plot. However, I have some additional insights. The grid corresponding to pzmap has, inherently, an sgrid. The handles of this grid do not show up in the gca properties. So you cannot do anything about it. Even the pzoptions does not enable you to modify those settings. Additionally, the additional Y-Ticks correspond to lines of constant natural frequencies.
Alternatively, it is better to use the sgrid command directly. To choose the constant damping lines,
z = [0, 0.25, 0.5, 0.75, 1];
To remove the additional Y-Ticks,
wn = [];
Now, use sgrid and grid command to get whatever you want.
sgrid(z,wn);
grid;
I can't still change any properties of the grid lines associated with sgrid but it still improves the look of the plot. The question is still open to investigation.
I use plotyy to put two plots in one graph:
f = figure('Color','white');
[ax,p1,p2] = plotyy(xx, yy1, xx, yy2);
ylabel(ax(1),'Phase','FontSize',18);
ylabel(ax(2),'Spectrum','FontSize',18);
set(ax,{'ycolor'},{'k';'k'});
set(p1,'LineWidth',2,'Color',[0.4940,0.1840,0.5560]);
set(p2,'LineWidth',2,'Color','red');
xlabel(ax(1),['Frequency [THz]'],'FontSize',18);
set(ax,'FontSize',14)
Figure is displayed perfectly, but when I try to save it as fig something like misaligned boxes appears.
I tried to use linkaxes, but with no result.
plotyy has been one of my favorite MATLAB functions to love to hate. It's a really useful function that I always seem to run into bugs with, to the point where I've completely stopped using it in favor of just stacking two (or more) axes objects and plotting to them separately. You can then set the Position property of the 'sub' axes to the same as your primary axes and they will stack nicely.
A functional example:
xx = linspace(-15,15,100);
yy1 = sin(xx);
yy2 = cos(xx);
f = figure('Color','white');
ax(1) = axes('Parent', f);
ax(2) = axes('Parent', f, 'Color', 'none', 'XTick', [], 'YAxisLocation', 'right');
p1 = plot(ax(1), xx, yy1);
hold(ax(2), 'on'); % Hold to preserve our axes properties set above
p2 = plot(ax(2), xx, yy2);
hold(ax(2), 'off');
ylabel(ax(1),'Phase','FontSize',18);
ylabel(ax(2),'Spectrum','FontSize',18);
set(ax,{'ycolor'},{'k';'k'});
set(p1,'LineWidth',2,'Color',[0.4940,0.1840,0.5560]);
set(p2,'LineWidth',2,'Color','red');
xlabel(ax(1),'Frequency [THz]','FontSize',18);
set(ax,'FontSize',14)
set(ax, 'ActivePositionProperty', 'position'); % Resize based on position rather than outerposition
set(ax(2), 'Position', get(ax(1), 'Position')); % Set last to account for any annotation changes
Along with stacking the axes you will also note that I have set the ActivePositionProperty to position (rather than outerposition). MATLAB resizes axes automatically when the Units property is set to Normalized, and it seems like this is the main spot where the issue is arising. On resizing, MATLAB also modifies the OuterPosition value for the second axes, causing it to resize the plot portion. The difference is small, [0 0 1 1] vs. [0 0.0371 1.0000 0.9599] in my case, but the effect is obviously very pronounced. You can use get and set to fix this, but you'll have to do it on every resize which is fairly annoying. The alternative is to resize based on the Position, which seems to alleviate the issue and is a tweak present in the R2015b implementation of plotyy. This also fixes plotyy except for cases where the window is very small, so I have left my answer with the more generic approach.
Please, create two functions to be able to reproduce what I mean:
First function:
function testPlot1()
pointData = rand(20000,3);
figure;
%hold on; % <- if commented out, does not work
plot3(pointData(:,1), pointData(:,2), pointData(:,3),'Marker', '.', 'MarkerEdgeColor', 'b','MarkerSize', 5, 'LineStyle', 'none');
axis equal;
xh = xlabel('X');
yh = ylabel('Y');
zh = zlabel('Z');
set([xh,yh, zh],...
'fontweight','bold',...
'fontsize',14,...
'color',[0,0,0]);
view(0,20);
end
Second function:
function testPlot2(fighandle)
axes(fighandle);
hold on;
plot3([0 3],[0 3],[0 3], 'r', 'LineWidth', 10);
end
If you now call
testPlot1();testPlot2(gca)
you will get the following:
If you however uncomment the "hold on" line in testPlot1() and call the above statement again, you will get:
To me this is unclear behavior. In the first case, testPlot1() creates a figure, draws the point cloud into it and modifies the axes properties. Then the call to testPlot2(gca) adds the line to the figure, but the line is clipped.
In the second case however the line is not clipped anymore. Why is it now not clipped and previously it was?
It seems to be related to the changes I make in the axes properties in testPlot1(). Could somebody explain this behavior to me? (why does it work with hold on, what do my changes in the axes properties cause)
hold on is a Matlab command (hold off turns it off again), where you can draw multiple elements on a single figure without the previous elements being erased.
What happens
If you call the plot function, a figure is created (or an already exisiting figure is used!) and Matlab draws a new plot into that figure. The previous plot that was in that figure is gone.
If you want to add more points to your plot, you can call hold on and then call plot again, this time with different numbers and maybe a different colour or so.
However, if you forget to turn hold off again for the active figure, any drawing activity you do (like plot) will be added to the figure. This is what happens in your second image in your question. You drew some points in the range 0 to 1, and then in the second function, you add some more but in the range 2 to 3. As a result, the axes expand to the range of 0 to 3.
Alternatively, you can call figure, which will cause a new figure to appear. figure_handle = figure(); will return a figure handle, which you can pass to your function, in case you have multiple figures and want to change one of them after a while.
When the graph below is plotted, NSS1 which is simply a constant set equal to one is right on the top border of the graph and thus hard to see.
How can I change the length of the y-axis to say 1.2 so that the NSS1 can be seen more clearly?
lambda=5;
tau=0:30;
tau(1)=0.000001;
NSS1=1*ones(1,31);
NSS2=(1-exp(-tau/lambda))./(tau/lambda);
NSS3=((1-exp(-tau/lambda))./(tau/lambda)-exp(-tau/lambda));
%ylim([0, 1.2])
plot(tau,NSS1,'-k*',tau,NSS2,'-k+',tau,NSS3,'-ko');
xlabel('t = 0 to 30y', 'FontSize',30)
ylabel('yield','FontSize',30)
The reason why ylim doesn't work if you put it before the plot command is that there is no axes object it can relate to.
So there are two options:
First, you create an axes object and hold it with hold on, so the upcoming plot is plotted on the same axis.
ax = axes; hold on;
ylim([0, 1.2])
plot(tau,NSS1,'-k*',tau,NSS2,'-k+',tau,NSS3,'-ko');
or second, you plot first, the command automatically generates an axes object and you can modify its y-limits afterwards:
plot(tau,NSS1,'-k*',tau,NSS2,'-k+',tau,NSS3,'-ko');
ylim([0, 1.2])
I want to plot two (or more) graphs in Matlab. I want them to be aligned one above the second one above the third and so on. However subplot is not the case for me. I also don't want them both to be on the same graph in different colors, just to be one above the other. Is it possible? I'm searching for such a command but without any success.
Thanks in advance for hints!
If what you mean by "one above the other" is one "on top of another" then I think what You need to use is the axes command. Having said that, in order to have your plot be readable, I think more than two scales in the same plot makes it pretty hard to read.
This Matlab's help page shows you how to do it, the gist of it is shown in the following script:
y2 = 1000.*rand(100,1);
x2 = 0:99;
% Plot the first data set
hl1 = line(x1,y1,'Color','r');
% Get the axes and configure it
ax1 = gca;
set(ax1,'XColor','r','YColor','r')
%Create the new axes
ax2 = axes('Position',get(ax1,'Position'),...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none',...
'XColor','k','YColor','k');
% Plot the second data set with the new axes
hl2 = line(x2,y2,'Color','k','Parent',ax2);
The above script creates the following plot with one set of axes in red and another in black.
Hope this helps.