Set axis limits when plotting 2 vertical axes in MATLAB via plotyy - matlab

I have the following data sets to plot:
data1 = [ 3 6 99 4 5];
data2 = [ 0.2 1.5 1.75 1.0 1.2];
What's peculiar about my situation is that I need data point data1(3), which is equal to 99, not show up on the graph. I'm using 99 as a way of pushing observations outside the desired axis limits so that there are no visible observations for certain values of the independent variable. (I'm plotting the data points with markers only, no lines.)
While data1 and data2 have totally unrelated scales and meanings, they share the exact same dependent variable:
X=40:1:44
I'm plotting with the following commands, which I derived from the MATLAB plotyy documentation page:
[AX,H1,H2] = plotyy(X,data1,X,data2);
set(get(AX(1),'Ylabel'),'String','This is vertical axis 1')
set(get(AX(2),'Ylabel'),'String','This is vertical axis 2')
set(H1,'LineStyle','none','Marker','*');
set(H2,'LineStyle','none','Marker','s');
So far, so good. What I cannot figure out is how to enforce the correct limits on both of the vertical axes. My desired limits are:
ylimits1=[0 3]
ylimits2=[0 10]
How can I set limits for each vertical axis?
I have tried this
set(get(AX(1),'Ylim'),ylimits1)
set(get(AX(2),'Ylim'),ylimits2)
and
foo = gca
set(foo(1),'ylim',ylimits1);
set(foo(2),'ylim',ylimits2);
but neither work.

the following should work:
[AX,H1,H2] = plotyy(X,data1,X,data2);
set(AX(1),'ylim',ylimits1);
set(AX(2),'ylim',ylimits2);

some other random things you can do
x1 = 1:10
y1 = x1.^2
x2 = 10:120
y2 = sin(x2)
[AX,~,~] = plotyy(x1,y1,x2,y2);
set(get(AX(1),'Xlabel'),'String','both plots')
set(get(AX(2),'Ylabel'),'String','plot 2')
set(AX(1),'YLim',[1 25],'YTick',7:23)

Related

Equally spaced x-value for values that are not equally spaced

I'm trying to display a discrete plot with values on the x-axis that are not equally space but I want them to appear equally spaced. I would like a stem plot with the first stick not on the y-axis, and I'd also like to have an horizontal dashed line at y=1.
So far here is what I tried.
x = [10 50 150 3000];
y = [.6 .754 .853 .954];
xv = [1 2 3 4];
stem(xv,y);
set(gca,'XTickLabel',x);
Unfortunately, this is not what I expected. The value on the x-axis are not right and the sticks start on the y-axis and end on the figure edge.
How can I fix this?
EDIT: I initially forgot the horizontal dashed line. Added this.
You just need two tiny additions:
x = [10 50 150 3000];
y = [.6 .754 .853 .954];
xv = [1 2 3 4];
stem(xv, y);
xlim([min(xv)-1 max(xv)+1]); % <--
set(gca, 'xtick', xv); % <--
set(gca, 'xticklabel', x);
You (also) need to explicitly set the xtick option, so that only these ticks are drawn, and no other.
With xlim, you can manipulate the x-axis limits. (Left and right limit might be modified to your needs.)
To add the horizontal dashed line, just add the following at the end:
hold on;
plot([min(xv)-1 max(xv)+1], [1 1], 'k--');
hold off;
(Start and end points of the line might be modified to your needs.)
From Matlab R2018b on, you could also use yline.
The output then looks like this:
When you have a sequence of values that you want to plot equally spaced without any special treatment to what each value actually is, you're essentially defining a set of categories.
MATLAB is good at handling these nicely without any extra trickery to lay them out uniformly on your axes if you declare the values explicitly as categorical.
All you need, therefore, is:
x = [10 50 150 3000];
y = [.6 .754 .853 .954];
stem(categorical(x),y);
yline(1,'--');
ylim([0 1.5]) % Make some space on the y-axis so the horizontal line doesn't sit on the top edge

Stretch a polarplot() slice

I'm plotting some polar coordinates in Matlab. See example below:
I'm only plotting a slice but can't figure out how to stretch/ expand this slice, as there is more space in the figure window than used. Speaking in pictures I'd like to 'open it like a fan'.
Minimal working example:
th = linspace(-pi/2,pi/2,100);
polarplot(th,1.1+zeros(size(th)),'g');
ax = gca;
thetalim([-5 5])
rlim([1.05 1.12])
I've tried using ax.Position = [0 0 1 1]; similar to how it works in Cartesian plots but this does not seem to work here.
Any commands or tips I'm missing so far?
I can only think of a workaround solution: increase the theta values passed to polarplot to get larger angles in the graph, and then relabel the theta axis:
stretch = 3; % stretch factor
th = linspace(-pi/2,pi/2,100);
polarplot(th*stretch,1.1+zeros(size(th)),'g'); % apply strech to theta
ax = gca;
thetalim([-5 5]*stretch) % take stretch into account when setting theta axis limit
rlim([1.05 1.12])
ax = gca;
ax.ThetaTickLabel = strsplit(num2str((ax.ThetaTick/stretch))); % correct theta labels
In the last line I am keeping the default theta ticks and relabelling them. You may prefer to specify other values manually, such as
ax.ThetaTick = stretch*(-5:5); % specify theta ticks, including stretch
ax.ThetaTickLabel = strsplit(num2str((ax.ThetaTick/stretch))); % correct theta labels

How do I create a polar plot with concentric colored rings corresponding to single values in Matlab?

I am trying to create a plot that looks like this with rings of constant values (colors) extending from 0 to 100 in 10 unit increments.
Rings of single values extending outward from center
However, my code is not producing this, and I do not know where it has gone wrong.
% values representing the colors that each ring should be
% starting from the center and moving outwards in 10 unit increments.
values = [364,358,354,348,339,335,330,325,320,310];
xCoord = linspace(0,2*pi,10);
yCoord = linspace(0,100,10);
[TH,R] = meshgrid(xCoord,yCoord);
[X,Y] = pol2cart(TH,R);
[Z] = meshgrid(values);
contour_ticks = 300:5:375;
figure
hold on
contourf(X,Y,Z,contour_ticks);
a=gca; cb=colorbar; colormap('jet'); caxis([300 375]);
This produces a plot resembling this:
Incorrect plot
Any ideas what I'm doing wrong? Any help is greatly appreciated. Thanks.
If you just want to plot circles, you can use the following approach:
radii = 100:-10:10; %// descending order, so that bigger circles don't cover small ones
colors = parula(numel(radii)); %// or use some other colormap
for n = 1:numel(radii)
r = radii(n);
rectangle('Position', [-r -r 2*r 2*r], 'Curvature', [1 1], 'FaceColor', colors(n,:),...
'EdgeColor', 'none') %// plot each circle using sequential colors, no edge
hold on
end
axis equal
axis([-1 1 -1 1]*max(radii))

MATLAB: how to customize non linear X axis (for example ticks at 1,2,3,4,5,20,100,'string')

I'm using the MATLAB plot feature to compare two vectors. I would like my X axis to represent 1 through 7, and then 14, 21, and then a category at the end for points with undetermined X values..(I'm also not sure how to represent these numberless point (they have Y values, just no X values) I could assign a large number outside any of my X values (1000) to these points, do the 1-7,14,21,1000 and then change the 1000 label to my 'string for un-numbered points'. ??
Here is a way to do it based on the example by The Mathworks here.
The trick is to create 2 x axis with different ranges and make one of them transparent. You can then play around with its properties. I modified a bit their code but kept most of their comments because they explain well the steps.
For the demo I used scatter to represent the points and colored the "good" points in red and the other point (here only 1) in green. You can customize all this of course. For instance I used a value of 100 and not 1000 for the x value of the 2nd axes, but I'll let you figure out how to modify it all to change the output as you wish.
clear
clc
close all
%// Create axes 1 and get its position
hAxes1 = axes;
axes_position = get(hAxes1, 'Position');
%// Create axes 2 and place it at the same position than axes 1
hAxes2 = axes('Position', axes_position);
%// Your data go here.
x = [1 7 14 21 100];
y = rand(1, length(x));
%// Plot the two sections of data on different axes objects
hPlot1 = scatter(hAxes1, x(1:4), y(1:4),40,'r','filled');
hold on
hPlot2 = scatter(hAxes2, x(end), y(end),40,'g','filled');
%// Link the y axis limits and fontsize property of the axes objects
linkaxes([hAxes1 hAxes2], 'y');
linkprop([hAxes1 hAxes2], 'FontSize');
%// Set the x range limits and tick mark positions of the first axes object
set(hAxes1, 'XLim', [1 25], ...
'XTick', [1 7 14 21])
%// Set the x range limits and tick mark positions for the second axes object.
%// Also set the background color to 'none', which makes the background
%// transparent.Add the label for the "super points".
set(hAxes2, 'Color', 'none', ...
'YTickLabel', [], ...
'XLim', [95 100], ...
'XTick', 100,'XTickLabel',{'Super Points'})
And the output:
EDIT
If you wish to add a fit line, I suggest adding a 3rd axes at the same position than the other 2, make it transparent and remove its X- and Y-ticks.
i.e. Add something like this:
hAxes3 = axes('Position', axes_position,'Color','none','YTick',[],'XTick',[]);
And in the call to polyfit/polyval, in my example you want to get only the first 4 elements (i.e. the red ones).
Hence:
p = polyfit(x(1:4),y(1:4),1);
y_poly = polyval(p,x(1:4));
And then plot the line on hAxes3:
hPlot3 = plot(x(1:4),y_poly)
Output:

How to plot a group of subplots in fixed axes setting automatically in Matlab?

The plotting code is shown as:
figure;
snr_idx = 1:2:7;
for n = 1:4
subplot(2,2,n);
ith = snr_idx(n);
xx_cpd(:,n) = reshape(theta_est_s1(1,ith,:,1), 500,1);
yy_cpd(:,n) = reshape(theta_est_s1(2,ith,:,1), 500,1);
scatter(xx_cpd(:,n), yy_cpd(:,n), 30, 'o', 'LineWidth', 5e-5)
grid on
xlabel('\phi_1 (deg)','fontsize',12)
ylabel('\phi_2 (deg)','fontsize',12)
title(['SNR = ',num2str(SNRvec(ith)), 'dB' ])
end
Where SNRvec is a vector as: [-3 0 3 6 9 12 15].
theta_est_s1 is a four-dimensional array, the size of theta_est_s1 is 2×7×500×3.
Then the resulting figure is shown as following:
However, the contrast between each subplot is not remarkable enough. I want all the subplots have the same axis setting as the first subplot, i.e. when the first subplot is made, the axis is fixed, which is shown as:
If I use axis([60 70 110 120]) command in this example, the resulting figure is correct. Nevertheless, the range of theta_est_s1 is not fixed. When the input data is changed, the maximum and minimum of theta_est_s1 are changed a lot. Therefore I cannot merely set the axis manually in a direct way.
Is there any method to figure out this issue?
Thanks!
Here is an idea if I got your question right:
Since MATLAB automatically resizes the axis to fit with the range of the data, you can let it set the limit for the first plot only, and then in each subsequent plot retrieve the x- and y limits and assign them to every subplot.
Example with your code:
figure;
snr_idx = 1:2:7;
for n = 1:4
subplot(2,2,n);
ith = snr_idx(n);
xx_cpd(:,n) = reshape(theta_est_s1(1,ith,:,1), 500,1);
yy_cpd(:,n) = reshape(theta_est_s1(2,ith,:,1), 500,1);
scatter(xx_cpd(:,n), yy_cpd(:,n), 30, 'o', 'LineWidth', 5e-5)
%// Get the axis limits after the 1st plot
if n == 1
X_axis_lim = get(gca,'XLim')
Y_axis_lim = get(gca,'YLim')
else %// After 1st iteration, adjust limits
set(gca,'XLim',X_axis_lim);
set(gca,'YLim',Y_axis_lim);
end
grid on
xlabel('\phi_1 (deg)','fontsize',12)
ylabel('\phi_2 (deg)','fontsize',12)
title(['SNR = ',num2str(SNRvec(ith)), 'dB' ])
end