I do not manage to change the order of plotted elements in this figure.
I would like to plot the line plot over the filled area.
The line should always be visible.
figure
yyaxis left
h = plot([0 10],[0 10],'LineWidth',5);
yyaxis right
f = fill([3 3 6 6],[0 10 10 0],'r');
% this does not work
h.ZData = ones(size(h.XData));
f.ZData = zeros(size(f.XData));
% using area instead of fill does not help
% plotting yyaxis right before yyaxis left does not help
I found a work-around solution by changing what is plotted in yyaxis left and yyaxis right.
The line is now plotted on top of the area.
However, the position of the axes is also switched.
I would like to keep it the way it is now (line should belong to left axis, area should belong to the right axis) since it looks nicer when I label it this way:
figure
yyaxis right
h = plot([0 10],[0 10],'LineWidth',5,'color','b');
yyaxis left
f = fill([3 3 6 6],[0 1 1 0],'r');
I managed to get it working with a combination of the hint from #LuisMendo and changing the 'ZData' attribute of my filled areas. Thank you all for your help!
Related
I'm trying to plot some data with two y-axes, but I get a lot of extra space - as you can see in the attached image.
My code is the following; the strange thing is that the last value in t is 50, not 60 like the plot would seem to show.
yyaxis left
plot(t,i_test*1000,'b-',t,iout*1000,'k-','LineWidth',2)
ylabel('Current (mA)')
yyaxis right
plot(t,vin,'r-','LineWidth',2)
ylabel('Voltage (V)')
xlabel('Time (s)')
Solution:
Adding axis tight like this fixed the issue. Thanks!
yyaxis left
plot(t,i_test*1000,'b-',t,iout*1000,'k-','LineWidth',2)
ylabel('Current (mA)')
axis tight
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.
I would like to place an arrow over a legend in a matlab plot but when I add the arrow, the legend defaults to being "on top" (see the picture, the black line being covered by the legend).
Is there a way to push a subfigure, such as an arrow, to the "top" so that it appears over all other component of the figure, including the legend? I've tried to use uistack but that doesn't seem to work with legends. uistack as the doc says should "Reorder visual stacking of UI components".
edit:
Very simple example: the line that I'm drawing should appear on top of the legend.
figure;
b = bar(1:3,rand(3));
hold on;
p = plot([0,3],[0,.5],'Color','k','linewidth',1.5); % my arrow
l = legend(b,'value','Location','SouthWest','AutoUpdate','off');
uistack(l,'bottom');
You can make the legend background transparent - so you will see your arrow through the legend
figure;
b = bar(1:3,rand(3));
hold on;
p = plot([0,3],[0,.5],'Color','k','linewidth',1.5); % my arrow
l = legend(b,'value','Location','SouthWest','AutoUpdate','off');
l.BoxFace.ColorData = uint8([255 255 255 127]');
l.BoxFace.ColorType = 'truecoloralpha';
The ColorData Property is [R G B Transparency]
For Info: This was done using R2015b.
You can copyobj the current graphical axes gca and set its Color property to none. This method will draw the line over the legend's patches and associated texts.
Explanation : Copyobj will copy and display all the axes related to the bar and line but not the legend (legends have axes on their own). The display of the copied axes will overlay perfectly with the original one. And 'Color','none' makes the white background of the copied axes transparent, thus making the legend visible again but visible under the line.
Here is the code
f = figure;
b = bar(1:3,rand(3));
hold on;
p = plot([0,3],[0,.5],'Color','k','linewidth',1.5); % my arrow
l = legend(b, 'Location','SouthWest');
% add some magic
hax = copyobj(gca, f); % copy the current axes to the figure
set(hax, 'Color', 'none') % set the new axes's background transparent
What MATLAB version do you use? uistack seems to not work on legends anymore, since MATLAB 2015b (see this similar problem).
If, as you say, the line can be appear at any place, the best workaround may be choosing the best legend location
l = legend(b,'value','Location','Best','AutoUpdate','off');
I am trying to create a plot of failure strength vs material stiffness. However, the stiffness can be given as either [Pascal] or [Shore A] - I would like to use both in a double axis plot.
I've tried using plotyy but it will not allow me to have one line plot, nor does it allow the non-linear relation between Pascal and Shore A. I would like to plot one of them and then manually add the spacing between the others ticks.
Preferably I would like the stiffness on the x-axis, but y-axis can do if it is easier.
Any help is most welcome!
Example picture of what I'm trying to do
This may help you when you need double x-axes and double y-axes plot, but if you need single y-axes and two x-axes you can modify accordingly:
This example shows how to create a graph using the bottom and left sides of the axes for the first plot, and the top and right sides of the axes for the second plot.
Create the data to plot.
x1 = 0:0.1:40;
y1 = 4.*cos(x1)./(x1+2);
x2 = 1:0.2:20;
y2 = x2.^2./x2.^3;
Use the line function to plot y1 versus x1 using a red line. Set the color for the x-axis and y-axis to red.
Note: Starting in R2014b, you can use dot notation to set properties. If you are using an earlier release, use the set function instead, such as set(ax1,'XColor','r').
figure
line(x1,y1,'Color','r')
ax1 = gca; % current axes
ax1.XColor = 'r';
ax1.YColor = 'r';
Create a second axes in the same location as the first axes by setting the position of the second axes equal to the position of the first axes. Specify the location of the x-axis as the top of the graph and the y-axis as the right side of the graph. Set the axes Color to 'none' so that the first axes is visible underneath the second axes.
ax1_pos = ax1.Position; % position of first axes
ax2 = axes('Position',ax1_pos,...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none');
Use the line function to plot y2 versus x2 on the second axes. Set the line color to black so that it matches the color of the corresponding x-axis and y-axis.
line(x2,y2,'Parent',ax2,'Color','k')
The graph contains two lines that correspond to different axes. The red line corresponds to the red axes. The black line corresponds to the black axes.
Source:
http://www.mathworks.com/help/matlab/creating_plots/graph-with-multiple-x-axes-and-y-axes.html
The following code produces a plot with two lines reffering to the left y-axis and one line referring to the right y-axis. Both plots have their own legend, but I want only one legend listing all 3 lines. I tried to just put the 'y1','y2' strings into the 2nd legend-command as well, but that didn't work out.
line(x,y1,'b','LineWidth',2)
line(x,y2,'Color',[0,0.6,0.5],'LineWidth',2)
legend('y1','y2');
ax1 = gca;
ax2 = axes('Position',ax1.Position,'YAxisLocation','right', 'Color','none','YColor',[255,127,80]/256);
linkaxes([ax1,ax2],'x');
line(x,y3,'Parent',ax2,'LineWidth',2,'Color',[255,127,80]/256)
legend('y3')
This is a tricky problem since the legend are somehow connected to the axes. Since you will be creating 2 axes, hence there will be 2 legends. However there is a trick to achieve what you want. Firstly, plot all line on the same axes, then run legend. Then create 2nd axes and then move the third line to the 2nd axes. So your code should look like this:
% line
line(x,y1,'b','LineWidth',2)
line(x,y2,'Color',[0,0.6,0.5],'LineWidth',2)
l3=line(x,y3,'LineWidth',2,'Color',[255,127,80]/256)
% legend
legend('y1','y2','y3');
% 2nd axes
ax1 = gca;
ax2 = axes('Position',ax1.Position,'YAxisLocation','right', 'Color','none','YColor',[255,127,80]/256);
linkaxes([ax1,ax2],'x');
% move l3 to 2nd axes
set(l3,'Parent',ax2);
If you want to use 'DisplayName', it meant to be used with line
line(x,y1,'Color','b','LineWidth',2,'DisplayName','y1');
line(x,y2,'Color',[0,0.6,0.5],'LineWidth',2,'DisplayName','y2');
legend('show');