Give axes priority over plotted line without giving grid priority - matlab

In my previous question I asked how to give axes and tick marks priority over the plotted line. The correct solution was:
set(gca,'Layer','top');
However in the case that I also want to plot a grid on the figure this gives the grid priority over the plotted lines as shown in the attached figure when exported as an .eps file. This is undesirable and leads to a dashed appearance to the blue line.
How can I give priority to axes and tick marks but not give priority to the grid?

The 'Layer' property of an axes object controls the layering of the axes, tick marks, and grid lines, so they can't be layered separately. Your options are:
Stack a couple of axes on top of each other with the same limits, with the bottom axes having grid lines and no data plotted and the top axes having your data and axes ticks that are layered on top.
Plot your grid lines yourself first, then plot your data on top of them, For example:
[xGridv, yGridv] = meshgrid([0.1 0.2 0.3], [0 1.7]); % Vertical grid lines
[yGridh, xGridh] = meshgrid([0.5 1 1.5], [0 0.32]); % Horizontal grid lines
hold on;
plot(xGridv, yGridv, 'k:');
plot(xGridh, yGridh, 'k:');
% Plot your data

Related

Ticks missing in contourf

I want to plot ticks at logarithmic values (without labels, only the ticks). For some reason the following code doesn't plot them (set(gca,'XTick') doesn't do anything):
figure1=figure(1)
axes1 = axes('Parent',figure1,'YScale','log','XScale','log');
grid(axes1,'on');
hold(axes1,'on');
[C,h]=contourf(lamx(2:NKX+1),lamz(2:NKZ+1),phi2d(2:NKX+1,2:NKZ+1)',[10],'LineColor','none');
clabel(C,h);
axis tight;
axis([lamx(end) max(lamx) lamz(end) max(lamz)])
xlabel('\lambda_x','Fontsize',20);
ylab=ylabel('\lambda_z','Fontsize',20);
set(gca,'XTick',0.1:0.1:1)
grid on
set(gcf, 'PaperPositionMode','auto');
set(ylab, 'Units', 'Normalized', 'Position', [-0.1, 0.5, 0]);
set(gca,'linewidth',1.5,'FontSize',16)
colormap(flipud(gray(256)));
colorbar;
print('-dpng','-opengl','-r1200','2dspec')
How could the ticks be plotted?
The ticks in your example are obscured by the Contour object itself. The order in which the Axes elements are drawn relative to objects within it is controlled with the Axes Layer property.
The default value for this property is bottom which means anything like a filled contour drawn in the axes will be drawn on top of the ticks, and you won't be able to see them. The contourf function obviously knows this isn't a helpful default for plots that will obscure the ticks in their entirety because it usually changes the property to top when you call it – but only when the Axes NextPlot is set to replace. By calling hold on you also cause contourf to leave that property alone, so it ends up staying at bottom.
In your example you can deal with this in one of two ways.
As it's currently written, there no intentional effect of the hold(axes1,'on'); line, because you're only adding one plot. So you could just remove that line if your full code doesn't rely on it. Otherwise,
Set the Layer property to top from the outset when you create the axes:
axes1 = axes('Parent',figure1,'YScale','log','XScale','log','Layer','top');

Vertical lines for Bode plots in Matlab

I have graphed a Bode plot for my transfer function, and I was wondering if there is some way to insert either horizontal or vertical lines to show a specific value for the gain/phase angle or frequency?
I have found with the following code I can draw a horizontal line on the phase angle graph:
x = linspace(10^-1,10^2,100);
for bleh = 1:length(x)
y(bleh) = -30.9638;
end
bode(num, den)
hold on
plot(x,y)
But this does not seem to apply in the gain graph, nor does my limited knowledge (and only way that makes sense to me) of vertical lines. I tried:
y1 = get(gca,'ylim');
w1 = 1.2;
bode(num, den)
hold on
plot(x,y,[w1 w1],y1)
But I only get the one horizontal line as was done from the above code.
Is this a possibility?
(Using R2017a, if that matters.)
I'm not sure I've understood you question, nevertheless, I propose the following.
When there are more one axes in a figure, as it is the case of the bode diagram, if you want to add something in a specific axes (or in all) you have to specify, in the call to plot the handle of the axes.
So, to add lines in the bode diagram, you have first to identify the handles of the two axes: you can do it in, at least two way:
using the findobj function: ax=findobj(gcf,'type','axes')
extract them as the Children of the figure: ax=get(gcf,'children')
Once you have the handles of the axes, you can get their XLim and YLim that you can use to limit the extent of the line you want to add.
In the following example, I've used the above proposed approach to add two lines in each graph.
The horizontal and vertical lines are added in the middle point of the X and Y axes (problably this point does not have a relevant meaning, but it is ... just an example).
% Define a transfer function
H = tf([1 0.1 7.5],[1 0.12 9 0 0]);
% PLot the bode diagram
bode(H)
% Get the handles of the axes
ax=findobj(gcf,'type','axes')
phase_ax=ax(1)
mag_ax=ax(2)
% Get the X axis limits (it is the same for both the plot
ax_xlim=phase_ax.XLim
% Get the Y axis limits
phase_ylim=phase_ax.YLim
mag_ylim=mag_ax.YLim
%
% Define some points to be used in the plot
% middle point of the X and Y axes of the two plots
%
mid_x=(ax_xlim(1)+ax_xlim(2))/2
mid_phase_y=(phase_ylim(1)+phase_ylim(2))/2
mid_mag_y=(mag_ylim(1)+mag_ylim(2))/2
% Set hold to on to add the line
hold(phase_ax,'on')
% Add a vertical line in the Phase plot
plot(phase_ax,[mid_x mid_x],[phase_ylim(1) phase_ylim(2)])
% Add an horizontal line in the Phase plot
plot(phase_ax,[ax_xlim(1), ax_xlim(2)],[mid_phase_y mid_phase_y])
% Set hold to on to add the line
hold(mag_ax,'on')
% Add a vertical line in the Magnitide plot
plot(mag_ax,[mid_x mid_x],[mag_ylim(1) mag_ylim(2)])
% Add an Horizontal line in the Magnitide plot
plot(mag_ax,[ax_xlim(1), ax_xlim(2)],[mid_mag_y mid_mag_y])
Hope this helps,
Qapla'

Matlab scatter markers bleed over edge of plot

I notice that for scatter plots and for other kinds of plots like bar plots, often the markers bleed over the edge of the plot limits. The picture attached to this question is an example: you can see the plot markers going over the boundary. Can this be prevented, and if so how?
The markers themselves are not affected by the axes Clipping property
Clipping does not affect markers drawn at each data point as long as the data point itself is inside the x and y axis limits of the plot. MATLAB displays the entire marker even if it extends slightly outside the boundaries of the axes.
The "solution" would be to add a small amount of padding around your plot so that the entirety of your marker falls within the axes.
The following pads the x and y range by 1%
xlims = get(gca, 'xlim');
ylims = get(gca, 'ylim');
set(gca, 'xlim', xlims + [-0.01 0.01] * diff(xlims), ...
'ylim', ylims + [-0.01 0.01] * diff(ylims));
This isn't an ideal approach, but I drew white rectangles over the areas outside of the ranges of the axes.
I generate a similar plot:
x=0:.02:1; plot(x,sin(2*pi*x),'o-')
Then, I use the following code:
xl = get(gca,'XLim');
yl = get(gca,'YLim');
set(gca,'clipping','off')
extremes = [xl(2)-xl(1), yl(2)-yl(1)];
rectangle('Position',[xl(1)-extremes(1), yl(2) , 3*extremes(1), extremes(2)],'FaceColor',[1 1 1],'EdgeColor','none'); % Top
rectangle('Position',[xl(1)-extremes(1), yl(1)-extremes(2), 3*extremes(1), extremes(2)],'FaceColor',[1 1 1],'EdgeColor','none'); % Bottom
rectangle('Position',[xl(2) , yl(1)-extremes(2), extremes(1), 3*extremes(2)],'FaceColor',[1 1 1],'EdgeColor','none'); % Right
rectangle('Position',[xl(1)-extremes(1), yl(1)-extremes(2), extremes(1), 3*extremes(2)],'FaceColor',[1 1 1],'EdgeColor','none'); % Left
set(gca,'XLim',xl);
set(gca,'YLim',yl);
set(gca,'box','on')
set(gca,'Layer','top')
This code notes the existing ranges of the axes and draws rectangles outside of them. After the rectangles are drawn, the ranges of the axes are restored, and the axes are brought to the front.
I populated extremes arbitrarily. It could be made larger if the axes region of the figure occupies a much smaller portion, or smaller if there are other axes regions at risk for being overlapped.
Here is the end result.

Plot with multiple axes but only one legend

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');

Matlab Grid lines with different color on one axis

I have reviewed the previous questions as described in Minor grid with solid lines & grey-color but It didn't help me solve my problem. My issue is entailed with xticks. I want my grid lines to appear at specific points on xaxis and some other grid lines to appear at different points with some different colors. Something like this:
plot(x,y,'--g')
set(gca,'Xcolor',[0 0 0],'Xtick',[12e3,14e3,18e3,23e3,30e3,37e3,57e3],
set(gca,'Xcolor',[0.5 0.9 0.5],'Xtick',[10e3 16 28e3]);
The problem is that the later xtick labels overwrites the previous ones. I'd like to retain the xlabels of the previous ones.
Create a 2nd axis.
x=-3.14:.1:3.14;
y=sin(x);
h=plot(x,y);
ax1=findobj(gcf,'Type','axes'); %save first axis handle
%set first stype
set(gca,'Xcolor',[0 0 0],'Xtick',[-3,-2,-1,1,2,3],'gridlinestyle','-','xgrid','on')
%create new axis
ax2=axes('position',get(gca,'position'),'Visible', 'on');
set(ax2,'YTick',[],'Xcolor','blue','Xtick',[-2.5 0 2.5],'xgrid','on','color','none'); %color none to make the axis transparent
set(ax2,'xlim',get(ax1,'xlim')) %resize 2nd axis to match 1st
Produces: