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.
Related
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
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'
I am plotting x and y coordinates together with some images but the images are becoming extremely large compared to the axis. How can i set the figure resolution or size so that an image can fit in a small axis range rather than covering the whole graph and also modify the axis range.
Figure without images (below).
Matlab code:
for l = 1:size of array
colormap('gray');
imagesc(X,Y, imrotate(imresize(img,[100 100]),180));
end
By default, imagesc will plot the image using indexed coordinates (pixel spacing of 1). Note the axes limits on this figure:
You can change this by altering the XData and YData properties of the image.
him = imagesc(rand(4), 'XData', [0,1], 'YData', [0 1])
Notice that this changed the scaling of your image. I'm not sure what coordinate system your points are (and if you can provide a little more information I can help you better), but you can adjust the XData and YData to be the appropriate values to match your points.
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
I would like to plot a line, and in grey-shaded X% deviation of a signal, in MATLAB. Then, I'd plot another signal and see (visually) how much of the second signal is outside the gret-shaded area.
The task I'd like to get help done is the shaded area: similar to the image attached below.
I am aware of similar solutions with errorbar, but I think this is a much clearer plot to visualize.
If for example I had:
x = 0:0.1:10;
y = 1 + sin(x);
What would the 5% grey-shaded plot of y look like? (that area?)
See this answer for an example: MATLAB fill area between lines
Do you have the error of y at each sample in x? Let's assume you have and the upper bound is in variable yu and the lower bound in variable yl. Then you could plot it using:
x = 0:0.1:10;
y = 1 + sin(x);
% I create some yu and yl here, for the example
yu = y+.1;
yl = y-.1;
fill([x fliplr(x)], [yu fliplr(yl)], [.9 .9 .9], 'linestyle', 'none')
hold all
plot(x,y)
fill(X,Y,ColorSpec,...) plots a polygon with edges specified in the first two parameters. You have to fliplr (flip left-right) the arrays, so that it correctly draws the shape of the area to be filled 'in a circle' around it. The [.9 .9 .9] is the colour specification, in this case a light grey. I removed the edge by setting no line, to make it even more similar to your desired plot. One detail: plot the filled area before plotting y, because the last plotted object goes on top of the others.