Matlab: Multiply vertical axis of hist plot by a number - matlab

The hist function in matlab plots the frequency of the data points in the vertical axis. What should I do if I want to multiply the frequency by a number.
For example if an object points at North 10 times during the entire recording of data and each time, it stays in the North position for 5 seconds. Instead of having the hist plot show that the object pointed at North 10 times, I would like it to show that it pointed at North for a total of 50 seconds.

You can use the histc (or histcounts in 2014b) function to do the bin counting without plotting the data, then plot using bar.
directions = rand(1000, 1)*360;
% note that histc counts the last element as exactly equal, so I pad
edges = [0:5:360, inf];
counts = histc(directions, edges);
multiplier = 5;
bar(edges(1:end-1)*multiplier, counts(1:end-1))

Related

MATLAB Surf plot with bins

I have a nxm matrix where n is the number of bins in the x axis and m is the number of bins in the y axis. Each position in the matrix has a number which shows how many data points are in matching x-y bin ranges from my raw data and when surf plotted results in a density plot.
The problem is if I have 100 x-bins and 50 y-bins the axis of my surf plot will be 0-100 on the x-axis and 0-50 on the y-axis. Which makes sense because I am doing surf(Matrix).
But infact I want the x and y axis to be from 0-5 for example. Therefore the number of bins for x and y will determine only the resolution of the plot. Low number of bins = low resolution. High number of bins = high resolution. When for the whole time the axis of the plot are 0-5.
In a nutshell is it possible to plot a matrix of varying size that is used for a surf plot into pre-assigned axis values?
(Of course doing axis([0 5 0 5]) will not work)
Found it difficult to word the question but hopefully it makes sense.

plotting data between concentric circles of known radii

I have a vector of 1000 random numbers biased towards the bounds of 540 and 600. I need to plot this data as a wriggly circular path between two concentric circles of radii 540 and 600 respectively. How do I do this?
Presently, I'm able to plot the concentric circles of given radii, but if I try to plot the given random data which is between the bounds 540 and 600, it is plotted along the width between the two concentric circles. I want it to be plotted as a noisy circular curve between the concentric circles.
I hope I'm able to explain my point
If anyone can tell me, how do I do that. Thanks
Here is the link to my previous post, wherein I had to generate random numbers biased towards the two well defined bounds
Generating random numbers in matlab biased towards the boundaries
Now I need to plot the same data, as explained above.
This is the image I get:
What you actually want is a circular plot, so the first idea that comes to my mind is to use polar coordinate.
First we get your sample of around 1000 random datas biased to the bounds of your [540 600] interval following that.
Note that this algorithm will not always get you exactly 1000 values as the out of bound values are removed.
So we'll do something like this :
%Get the size of the sample
P=length(X);
% Generate P Angles uniformly distributed between 0 and 2*pi*(P-1)/P
% Note generating an angle equal to 0 and an angle equal to 2*pi would
% mean that we have 2 points with the same angle, and that s something
% you generally want to avoid
Angles=(0:P-1)*(2*pi/P);
% Plot your points with the markers (polar coordinates) in '-+',
% - means that you want a line to be drawn between the points and
% + means that you want a + marker on every point
plot(X.*cos(Angles),X.*sin(Angles),'-+');
%tell matlab to wait so you can add the circles
hold on
% add circle of 540 radius
plot(540*cos(Angles),540*sin(Angles),'-r');
%add circle of 600 radius
plot(600*cos(Angles),600*sin(Angles),'-r');
For the final result of :
Update : About getting the angles randomly distibuted
We'll have to define our Angles diffrently. We still need a vector of length P, but randomly distributed. This can be achieved by taking P random numbers between 0 and 1, and then multiply this vector by 2*pi in order to get randomly distributed values between 0 and 2*pi.
Last step is to order this vector in order to keep the ordering of your data.
Temp=rand(1,P)*2*pi;
Angles=sort(Temp);
For a final result of :
Another lead woult be to take a sample of 1000 gaussian random numbers and use them modulo 2*pi :
Angles=sort(mod(randn(1,P)*2*pi,2*pi));

Set an x-axis of a histogram in matlab to get a subset of the histogram

I have a histogram I plotted in matlab and I want to work with only a section of that histogram. I have found how to change the x-axis overall, but that just plots the entire histogram over this new axis instead of just pulling the subset of the histogram. Is there any way just to work with that section of the histogram by selecting a certain x-axis?
You can plot exactly as much of the histogram as you want by choosing a subsection of the matrix,
bins = 100
xmin = 40
xmax = 60
[f,x]=hist(randn(1000000,1),bins);
bar(x(xmin:xmax),f(xmin:xmax))
Alternatively, you can plot over a specified range of x bin values,
xvalues = -1:0.1:0.9;
[f,x]=hist(randn(1000000,1),xvalues);
bar(x,f,'b')
but all the values outside this range will be collected in the bins at either end if the range.

Is there any way to restrict the plots in one grapgh?

I'm trying to plot several signals in one graph and i would like to restrict them and sort of minimize it so all my signals will be clear (more or less).
I have no idea how to do it. I'm adding an image so what i need to do will be clearer.
My data changes but in general it's the mean intensity of each column of a certain area in an intensity image.I tried to do it like with the same idea as you but i don't get the right plot as i wanted. A is the relevant matrix,b is the matrix with shifted values:
for i=1:20
b(i,:)=A(i,:)+(100*i);
plot(b(i,:))
hold on
end
I will also add 2 images: one is the plot of all the 20 signals that i get and the other one is the plot of only the first signal. I don't understand why do they look so different.
You can try something like that :
x = [1:100]; %Distance 1 to 100
y = F(x) % Your first function (signal)
y2 = 0.5*G(x) % Your second function (signal)
plot(x,y,x,y2); % plot both function in a single plot.
hleg1 = legend('Intensity t1,'Intensity t27');
So you have your signal at intensity t27 half cut for each value ( 0.5 ), so it shift down.

axis equal in a Matlab loglog plot

In Matlab the command 'axis equal':
sets the aspect ratio so that equal tick mark
increments on the x-,y- and z-axis are equal in size. This
makes SPHERE(25) look like a sphere, instead of an ellipsoid
However, when using the loglog plotting function, this doesn't work "properly". What I would like to happen is that I get an aspect ratio so that a given factor occupies the same visual distance. What actually happens is that
>> loglog(2.^[1:20]*1e10,(2.^[1:20]).^2)
>> axis equal
results in
rather than
So that the slope 2 (from the squared) could be easily observed, and so that there wouldn't be all that extra white space.
My question is:
Is there a Matlab command that does this for me? Alternatively, has anyone solved this problem before?
One solution is for you to modify the axes limits and 'DataAspectRatio' properties yourself so that a decade on one axis equals a decade on the other. Here's how you can do it for your example:
loglog(2.^[1:20]*1e10,(2.^[1:20]).^2); %# Plot your sample data
xLimits = [1e10 1e16]; %# Limits for the x axis
yLimits = [1 1e12]; %# Limits for the y axis
logScale = diff(yLimits)/diff(xLimits); %# Scale between the x and y ranges
powerScale = diff(log10(yLimits))/... %# Scale between the x and y powers
diff(log10(xLimits));
set(gca,'Xlim',xLimits,'YLim',yLimits,... %# Set the limits and the
'DataAspectRatio',[1 logScale/powerScale 1]); %# data aspect ratio
set(gca,'XTick',[1e10 1e12 1e14 1e16]); %# Change the x axis tick marks
And here's the resulting plot:
Notice that the space between the 100 and 102 tick marks on the y axis spans the same number of pixels as the space between the 1010 and 1012 tick marks on the x axis, thus making a decade on one axis equal to a decade on the other.
If you don't want to change the axes limits, and instead want to use the default limits chosen by MATLAB, you can simply fetch the limits from the axes to perform the computations:
xLimits = get(hAxes,'XLim');
yLimits = get(hAxes,'YLim');
However, in order to disable MATLAB's automatic axes resizing behavior you will still have to either set the axes limits to the same values or set the limit mode properties to 'manual' when you update the 'DataAspectRatio' property:
set(gca,'Xlim',xLimits,'YLim',yLimits,...
'DataAspectRatio',[1 logScale/powerScale 1]);
%# OR...
set(gca,'XLimMode','manual','YLimMode','manual',...
'DataAspectRatio',[1 logScale/powerScale 1]);
If all of this seems like a lot of work, you can simplify things by putting it all into a function. I will actually be submitting a function decades_equal to the MathWorks File Exchange based on the code in this answer. For the time being, here is a trimmed down version (i.e. no error checking or help) that you can use:
function decades_equal(hAxes,xLimits,yLimits)
if (nargin < 2) || isempty(xLimits)
xLimits = get(hAxes,'XLim');
end
if (nargin < 3) || isempty(yLimits)
yLimits = get(hAxes,'YLim');
end
logScale = diff(yLimits)/diff(xLimits);
powerScale = diff(log10(yLimits))/diff(log10(xLimits));
set(hAxes,'Xlim',xLimits,...
'YLim',yLimits,...
'DataAspectRatio',[1 logScale/powerScale 1]);
end
And you can call the function as follows:
loglog(2.^[1:20]*1e10,(2.^[1:20]).^2); %# Plot your sample data
decades_equal(gca); %# Make the decades equal sizes
How it works...
You may be wondering what the logic is behind how I chose the scaling factors above. When trying to make the displayed size of a decade equal for each axes, we have to take into account both the number and sizes of decades within the axes ranges. In the above code, I am basically computing the average decade size for each axis, then using the ratios of the average decade sizes to scale the axes accordingly. For example, diff(yLimits) gives the total size of the y axis, and diff(log10(yLimits)) gives the number of decades (i.e. powers of ten) displayed on the y axis.
This may be easier to see if I reorder the operations in the above code like so:
yDecade = diff(yLimits)/diff(log10(yLimits)); %# Average y decade size
xDecade = diff(xLimits)/diff(log10(xLimits)); %# Average x decade size
set(gca,'XLim',xLimits,'YLim',yLimits,...
'DataAspectRatio',[1 yDecade/xDecade 1]);
And this will give the same scaling results as before.