how i can plot a graph with inetger number as input - matlab

how i can plot cos(3 pi/7 * n ) such that n be integer number in interval [x=0,x=10] in matlab?
i used this code
figure
X = linspace(0,2*pi,10)';
Y = cos(X);
stem(X,Y)
set(gca,'xlim',[0,10])
the graph that i get is this , but i want to show points of graph in integer number of x axis . how can i do that ?

Instead of using linspace for such a simple example as this one, you can just define your vector X as an integer vector taking steps of 1, from 0 to 10:
figure
X = 0:1:10;
Y = cos(3*pi/7*X);
stem(X,Y)
set(gca,'xlim',[0,10])
Below shows the plot generated by the code snippet above (bottom plot) as well as the same plot using step size 0.5 (X = 0:0.5:10, top plot).
Note that as Adriaan notes in the comments below, the default step size for ... = from:stepsize:to notation is 1, i.e., if omitting the stepsize and simply writing ... = from:to, a step size of 1 is used by default (stepsize=1).

Related

Generate a heatmap in a set X, Y, Z with Z being the intensity of the color

I have a numerical set X, Y, Z and I would like to reproduce a heatmap with these values. The size of the bin is 20 x 20 and the range of the X and Y axes are from -150 to 150 with Z being the color. Within that bin it should contain the average of the Z values in that range.
In Origin contains this tool to make a heatmap with the average of the values, but I would like to do it in MATLAB. The graph I made in Origin and that I would like to do in MATLAB can be seen in figure 1.
I've tried something like
load xyz.dat
x = xyz(:,1);
y = xyz(:,2);
z = xyz(:,3);
tbl = table(x,y,z);
h = heatmap(tbl,'x','y','ColorVariable','z','ColorMethod','mean');
But it printed this warning
Warning: Error updating HeatmapChart. Values in the source table variable 'x' are not grouped into discrete categories. Use the discretize function to group your values.
heatmap expects discrete x and y values. You goal is to bin your x and y's into 20 discrete bins and average the z values for each bin, but x and y themselves are continuous.
To achieve your goal take the advice of the warning message and use discretize to bin your x and y values.
% I used the following stand ins for your data:
% x = rand(540, 1);
% y = rand(540, 1);
n_bins = 20; % Number of grid cells
% If you want the width of the grid cell to be 20, use
% n_bins = (max(x) - min(x)) / 20;
x_discrete = discretize(x, n_bins);
y_discrete = discretize(y, n_bins);
tbl = table(X_discrete,y_discrete,z, 'VariableNames', {'x', 'y', 'z'});
h = heatmap(tbl,'x','y','ColorVariable','z','ColorMethod','mean');
Note: Why was this not a problem with the sample data?
Using your sample data,
x = [49.8, 14.5, -60.7, -21.6, -10.6];
y = [45.3, 7.9, 23.9, -58.5, -55.4];
z = [0.2 , -0.06, -0.35, -0.15, -0.08];
tbl = table(x',y',z', 'VariableNames', {'x', 'y', 'z'});
h = heatmap(tbl,'x','y','ColorVariable','z','ColorMethod','mean');
Does not throw an error because it treats each x and y value as a separate category. heatmap uses a call to categorical to transform the continuous values into categorical values.
Aside from not really providing the output you want (each point would be its own box instead of averaging grid cells), categorical seems to have a limit in how many categorical values it will create. I wasn't able to find any documentation about exactly what that limit is, but by experimentation, it tops out in the mid 200's. Since your vectors are 540 elements long, you get the warning about using discretize instead.

How to make multiple graphs with varying x-axis?

I need to plot multiple graphs in the same y-axis, but the x-axis is a bit tricky for me:
Assuming it goes from 0 to a, increasing by one, it needs to have an overall of a-1 different intervals.
Each one of them should finish at a, but it also has to have a different initialisation point. Only the first starts at 0, while each next one, starts by the previous plus one, as in the shape below. The two dashed lines, I used to visualise my thoughts as clear as I could, are not necessary.
I would appreciate any help!
Replicate your original interval 0 ... a a times (from my understanding, you'll have a intervals, not a-1), such that you get a matrix X of size [a x a+1]. Set the lower left triangle of X to NaN, so that the rows now represent your (shortening) intervals. Do your calculations on X. Pay attention, these have to support/neglect NaN values properly.
After that, you need to adjust the values in X properly, so that the intervals are plotted subsequently. Basically, we add some fixed value to each row.
Last, we need the proper xticks and xticklabels. Therefore, we extract all values from X and the modified X and get rid of the NaN values.
Here's a complete code snippet:
% Parameter
a = 7;
% Initialize intervals
X = repmat(0:a, a, 1);
X = X .* (ones(size(X)) + tril(nan(size(X)), -1));
% Calculation on these intervals; attention: there are NaN in X
Y = sin(X / a * 2 * pi);
% Modify X for plotting
X_plot = X;
X_plot(2:end, :) = X_plot(2:end, :) + cumsum(a:-1:2).';
% Get xticks
xt = X_plot.';
xt = xt(:);
xt(isnan(xt)) = [];
% Get xticklabels
xtl = X.';
xtl = xtl(:);
xtl(isnan(xtl)) = [];
% Plot
plot(X_plot.', Y.');
xticks(xt);
xticklabels(xtl);
The output (Octave 5.1.0, also tested with MATLAB Online) looks like this:
If you only want for example the start and end of each interval, you must further pre-process xt and xtl.
Hope that helps!

MATLAB: polyval function graphs multiple lines for N>1

I am trying to graph a polynomial function using the following code:
y = polyfit(P,C,3);
Line = polyval(y, P);
y =
2.0372e-14 -4.0614e-09 0.0002 2.6060
figure
plot(P,C,'.')
hold on
plot(P, Line, '-')
legend('Observations','y')
axis([0 90000 0 10])
The problem is, it produces multiple lines like this:
This problem does not occur if I set N = 1 or y = polyfit(P,C,1);. In that case I get a proper graph with one line:
How can I graph just 1 line for N = 3?
Here is an Excel version of what I am trying to produce in Matlab:
This is because your observations P are in an arbitrary order: Matlab is going from point to point in that order. You don't actually need to plot the fitted curve at each value P, you just need to plot the fitted curve over the range of P:
Pfitted = linspace(min(P),max(P),1000) % Generate 1000 equally spaced points
Cfitted = polyval(y,Pfitted) % Fit to these points
plot(Pfitted,Cfitted,'-')

Positive & Negitive Log10 Scale Y axis in Matlab

Hi i'm having a problem where I have a dataset which ranges between -10^3 to 10^3
I need to be able to plot this as with a log scale but semilogy cannot plot negative values
Say for example my data is:
x = [-3,-2,-1,0,1,2,3];
y = [-1000,-100,-10,1,10,100,1000];
(or in general y=sign(x).*10.^abs(x);)
How can I plot this in MATLAB with a log scale? If possible It would be great if the log scale ticks could be on the Y-axis too
Use your actual data as labels, but scale the plotted data with log10.
% data
x = -3:0.1:3;
y = sign(x).*10.^abs(x);
% scaling function
scale = #(x) sign(x).*log10(abs(x));
N = 7; % number of ticks desired
% picking of adequate values for the labels
TickMask = linspace(1,numel(y),N);
YTickLabels = y(TickMask);
% scale labels and plotdata, remove NaN ->inconsistency, do you really want that?
YTick = scale( YTickLabels );
Y = scale(y);
YTick(isnan(YTick)) = 0;
Y(isnan(Y)) = 0;
% plot
plot(x,Y)
set(gca,'YTick',YTick,'YTickLabels',YTickLabels)
grid on
For N = 7:
For N = 11
How to find a valid value for N?
The following function (thanks to gnovice) will return all possible values you could choose for N:
n = numel(x);
N = find(rem(n./(1:n), 1) == 0) + 1;
about the semilogy-style labels: by adding the following line before the plot:
YTickLabels = cellfun(#(x) ['10^' num2str(x)], num2cell(YTick),'UniformOutput',false)
you could at least achieve something like this:
not beautiful and not generic, but a good point to start for you.
The reason you can't make a logarithmic axis that crosses zero, is that it doesn't make sense!
Since a logarithmic scale is generally displayed as eg. 100 - 10 - 1 - 1/10 - 1/100 - ..., you would need an infinite amount of space to make the axis cross zero.
How about this:
x=logspace(-3,3);
y=sign(x).*10.^abs(x);
loglog(x,y)
#thewaywewalk has already given a beautiful solution to it. The one I'm suggesting is an epsilon improvement on it. If you make two changes
(a) Define a new MATLAB function signia that basically extracts the sign before a number.
function value = signia(x)
if(x>=0)
value = '';
else
value = '-';
end
and (b) make this little change that instead of
YTickLabels = cellfun(#(x) ['10^' num2str(x)], num2cell(YTick),'UniformOutput',false)
you use
YTickLabels = cellfun(#(x) [signia(x) '10^{' num2str(x) '}'], num2cell(YTick),'UniformOutput',false);
(notice the presence of curly braces), you'll get an improvement in the Y ticks display. I got the following.
enter image description here

MATLAB: How do I graph multiple functions on the same graph?

How can I graph multiple functions on the same graph/plot/Cartesian plane on MATLAB with domain and range restrictions?
For example I made up the following functions below. How would I graph the following on the same graph within MATLAB?
Function 1: x = -3 for 10 <= y <= 14
Function 2: y = -2x for -5 <= x <= -4
Function 3: (x-0)^2 + (y-12)^2 = 2.25 // Produces a circle
Function 4: y = 4 for -1 <= x <= 1
Matlab is a numerical computing environment, so you'll need to tell it what you're looking for while plotting.
In the case of your first example, you'll need to tell it which Y values to plot. Since X is always the same, you know it's going to be a line - so two points will be enough. Plot requires parallel arrays, so:
Function 1: x = [-3 -3]; y = [10 14]; plot(x, y);
To plot additional lines on the same graph, use the command hold on, which applies to the figure you just plotted. If you don't do this, new plot commands will erase the old plots.
Similarly,
Function 2: x = [-5 4]; y = -2*x; plot(x, y);
For circles/ellipses like #3, ezplot can be helpful, although you still have to specify the range.
Function 3: ezplot('x^2 + (y-12)^2 - 2.25', [-3,3,10,14])
The last one is easy, but let's say it were a curve instead. You'd want to plot more than just two x values. You can create a vector from a range like this: x = -1:0.1:1;, or an evenly space set of points from -1 to 1, with an interval of 0.1. Let's say you want to plot it on the same graph, and you've already done hold on. You want a different color, and you want to show the individual points that make up the line, you can use the third argument to the plot function:
Function 4: x = -1:0.1:1; y = 4 * ones(length(x)); plot(x, y, '-r.');
The second command here, y = 4 * ones(length(x)); simply creates a y vector that is the same length as x.