semilog plot: axes will not stay consistent - matlab

I am trying to get 5 different semi log x figures for 5 data sets (and each figure has a number of lines on its plot). The plot works well when I don't enter any data (i.e. the axis ranges are what I want them to be) but when I enter data, the axes ranges changes (the limits stay the same, but the spacing between different values changes). For example, for the first data set, I input it and 10^2 appears about 1/4 of the way across the x-axis, but I input the second data set and 10^2 appears 1/2 of the way across the x-axis. How can I get the axes to stay perfectly consistent regardless of whether the data changes?
My code is below:
function createfigure_log_orient_autocorr(X1, YMatrix1)
plot(X1,YMatrix1,'LineWidth',2);
set(gca,...
'YTickLabel',['0 ';'0.2';'0.4';'0.6';'0.8';'1 '],...
'YTick',[0 0.2 0.4 0.6 0.8 1],...
'XTickLabel',['0';'1';'2';'3'],...
'XTick',[1 10 100 1000],...
'XScale','log',...
'XMinorTick','on',...
'PlotBoxAspectRatioMode','manual',...
'PlotBoxAspectRatio',[1.999 1 0.5],...
'FontWeight','bold',...
'FontSize',16,...
'DataAspectRatioMode','manual',...
'DataAspectRatio',[1000 1 2],...
'XLimMode','manual',...
'XLim', [0 2000],...
'YLimMode', 'manual',...
'YLim', [0,1]);
I understand my question may be confusing, so I can try to clarify if anyone needs me to.

I'd use the function semilogx(...) instead of plot, and then follow it up with axis to set the limits I want.
More here.

Related

Plotting multiple fitobjects in the same figure in MATLAB 2016b

I have multiple fitobjects that I want to plot in the same figure. All curves are fitted from the same five points on the x-axes (ranging from 0.25 to 2.25). If I plot them individually the curve correctly spans only between does values, however, as soon as I add hold on to plot them in the same figure the first fitobject is plotted correctly, while the second spans from -Inf to +Inf, if I change the order of fitobjects the problem remains. So the first curve is always shown correctly the following ones are not. I am not even setting any axes properties yet. Also the two fitobjects have the same Boundaries for the fit.
Example code:
plot(fitobj{1}, 'r'); hold on %curve from 0.25 to 2.25
plot(fitobj{2}, 'b'); %curve is shown from -Inf to +Inf
Do you know why this is happening? Thank you

MATLAB focus plot and apply correct tick labels

I'd much rather be asking you about Bayesian analysis over this, but unfortunately, I am terrible with MATLAB plots (not due to a lack of effort though).
I have a plot attached. It contains 1739 days of data. I need to do the following three things:
Focus in on the plot so that the y axis limits are -1 and 1 (right now they are -4 and 14). I'm uninterested in any values beyond these limits.
Re-label the y axis from -1 to 1 in .10 increments.
Re-label the x axis so that it starts with 1, ends with 1739, and has enough points in between that it is still readable.
I've studied gca, datetick, ax=gca, etc. but I cannot accomplish any of these tasks without messing up the plot.
I am gracious for any assistance provided.
Changing the axis limits is very simple,
axis([1 1739 -1 1]) %// [xMin xMax yMin yMax]
And for the tick marks, do
set(gca,'XTick',-1:.1:1,'YTick',1:79:1739) %// 2*79 might be better than 79
after you create the plot. You can (should?) replace gca with the handle to the plot (do h=plot(... when you make the plot, then set(h,'XTick',...).
You should also go through Matlab Plotting Basics which goes through all this kind of stuff in good detail.

Matlab plotting through origin regardless of only negative or only positive data

this one should be really easy to answer, yet I am surprised it is nowhere described:
I have variable data, and often when I simply plot, I get a close-up on the y-axis (x-axis is time and starts always with a zero). So I get y-values from 16-17, but the zero is nowhere to be seen. I know you can give matlab an YLim value, yet sometimes because my data is variable, I get a range from -50-100 in y. If i had specified before that YLim is [0 20] I wouldnt see it at all, which is not what I want. I just always want to have the origin plotted with my data, how do I do that (without a rigid interval like [-1000 1000], since sometimes I have y values from -0,01-0,001 and wouldnt see it)? Please help if you have an idea!
Thanks!
UPDATE 1: perfectly solved!
Follow-up question:
There is one thing I didnt mention: I need to do this for all my 18 subplots. How can I avoid hardcoding it?
One way to do this is automatically is to use:
ylim([min([y 0]) max([y,0])])
this way, it will start or stop at 0 if 0 is not already in the range of y
or better, if you want to keep the rounded values matlab provides (eg plot on [0,6] and not on [0,5.872]), first plot your data with plot(x,y), then change the ylim values to 0 if needed:
ylim([min([ylim 0]) max([ylim 0])])
It's easy to manually modify axis size:
x = 1:10; %/ example x
y = 5 + rand(1,10); %// example y. Values between 5 and 6
plot(x,y) %// do the plot normally
ax = axis; %// get axis size
ax(3) = min(ax(3),0); %// if the y-axis lower limit is positive, make it 0
axis(ax) %// apply new axis size values
This also seems to work: just use
plot([x NaN],[y 0])
That is, include a point with x value set to NaN and y value set to 0. The point doesn't get plotted (because of the NaN value) but it forces the y axis to strech out to 0.

MATLAB: Density-time Plot

I have 11 1x50 matrices that contain densities. The first looks like [20, 20, 20... 20] and represents time=0. The second looks like [20, 19, 22,..], etc. and represents time=100. These continue to vary until t=1000.
What I'm hoping to do is to create a plot with the elements' position on the x-axis (50 positions for the 50 pieces of data in each) and time (0-1000) on the y-axis. Ideally, I'd like the plot to be completely filled in with color densities, and a colorbar on the side that shows what densities the color range represents.
Any help would be greatly appreciated!
Sort of inspired by: http://www.chrisstucchio.com/blog/2012/dont_use_scatterplots.html
Assuming you have (or can arrange to have) all those vectors as columns of a 11x50 matrix:
A = randi(100, 11,50); %//example data
you can just use
imagesc(1:50, 0:100:1000, A)
colorbar
axis xy %// y axis increasing, not decreasing
Example:
Looking at the comments, it will be easier to stack these vectors into a 2D matrix. You have 11 individually named vectors. Assuming that your vectors are named vec1, vec2, vec3, etc., create a 2D matrix A that stacks these vectors on top of each other. Also, you'll need to include an extra row and column at the end of this matrix that contains the minimum over all of your vectors. The reason why this is will be apparent later, but for now take my word for it as this is what you need.
In other words:
A = [vec1; vec2; vec3; vec4; vec5; vec6; vec7; vec8; ...
vec9; vec10; vec11];
minA = min(A(:));
A = [A minA*ones(11,1); minA*ones(1,51)];
As such, the first row contains the information at time 0, the next row contains information at time 100, etc. up to time 1000.
Now that we have that finished, we can use the pcolor function to plot this data for you. pcolor stands for pseudo-coloured checkerboard plot. You call this by doing:
pcolor(A);
This will take a matrix stored in A and produce a checkerboard plot of your data. Each point in your matrix gets assigned a colour. The colours get automatically mapped so that the least value gets mapped to the lowest colour while the highest value gets mapped to the highest colour. pcolor does not plot the last row and last column of the matrix, but pcolor does use all of the data in the matrix. In order to ensure that the colours get properly mapped, we need to pad your matrix so that the last row and last column get assigned to the smallest value over all of your vectors. As you want to plot all values in the matrix, that's why we did what we did above.
Once we do this, we'll need to modify the X and Y ticks so that it conforms to your data. As such:
pcolor(A);
set(gca, 'XTick', 0.5:5:51.5);
set(gca, 'XTickLabel', 0:5:50);
set(gca, 'YTick', 1.5:11.5);
set(gca, 'YTickLabel', 0:100:1000);
xlabel('Sample Number');
ylabel('Time');
colorbar;
What the code does above is that it generates a checkerboard pattern like what we talked about. This labels the Sample Number on the x axis while time is on the y axis. You'll see with the two set commands that I did, this is a bit of a hack. The y axis by default labeled the ticks going from 1 - 12. What I did was that I changed these labels so that they go from 0 to 1000 in steps of 100 instead and I also removed the tick of 12. In addition, I have made sure that these labels go in the middle of each row. I do this by setting the YTick property so that I add 0.5 to each value going from 1 - 11. Once I do this, I then change the labels so that they go from 0 - 1000 in steps of 100. I also do the same for the x axis in a similar fashion to the y axis. I then add a colorbar to the side as per your request.
Following the above code, and generating random integer data that is between 13 and 27 as per your comments:
A = randi([13,27], 11, 50);
minA = min(A(:));
A = [A minA*ones(11,1); minA*ones(1,51)];
We get:
Obviously, the limits of the colour bar will change depending on the dynamic range of your data. I used randi and generated random integers within the range of 13 to 27. When you use this code for your purposes, the range of the colour bar will change depending on the dynamic range of your data, but the colours will be adjusted accordingly.
Good luck!

Matlab Subplot Axes

I'm having a bit of a problem with what's happening to the axes of 9 plots that get subplotted together. I'm using subplot(3,3,x) to make a 3x3 grid of 9 plots, and custom labeling the ticks of the axes with
set(gca, 'XTickLabel', {'0,0','0,1','0,2','1,0','1,1','1,2','2,0','2,1','2,2'});
set(gca, 'YTickLabel', {'0,0','0,1','0,2','1,0','1,1','1,2','2,0','2,1','2,2'});
and the problem is that not all of the ticks specified show up on the subplots -- only about half of them, and they show up in the wrong places, at that.
I'm guessing this is matlab thinking that there isn't enough room to put all of the ticks and labels and showing a squeezed subset as a result, but it would look fine if it just did it. how do I make it all show up??
You can set the 'Xtick' & 'Ytick' property of the figure's axes. They define which ticks will be visible. In your case you want to show the first 9 xticks and the first 9 yticks - the following command will do it:
set(gca,'Xtick',1:9, 'Ytick',1:9)
In case you want to show every 2nd tick you would use:
set(gca,'Xtick',1:2:9,'Ytick',1:2:9)
Hope this helps.
You set custom tick labels with those commands, and they show up where the ticks are at that moment. You can see what the ticks are with
get(gca,'YTick');
For example:
plot(-2:2)
get(gca,'YTick');
returns [-2 -1.5 -1 -0.5 0 0.5 1 1.5 2]. If you now use
set(gca,'yticklabel',{'a','b','c','d','e'})
then those letters will appear at all ticks, starting from the first (-2) and since there are more ticks than ticklabels, the ticklabels will repeat, as you can see:
So these are ticks, but maybe you meant to just use labels, which I add with the following:
ylabel('this is the ylabel');
xlabel('and this the xlabel');
Play around with it and learn what's going, it's not that hard ;)
PS: with subplot, you can create different axes and set different ticks for each axes object separately. By default the axes are not linked or something, but completely independent! When you use gca, it returns the current axes, ie with subplot: the last one created or selected with subplot(3,3,x)!
So if you want to set ticks, labels are anything else on all the axes, you'll have to do it for all separately, ie:
subplot(3,3,1);
xlabel('x');
ylabel('y');
title('subplot (1,1)');
set(gca,'xticklabel',{'a','b','c'});
subplot(3,3,2);
xlabel('x');
ylabel('y');
title('subplot (1,2)');
subplot(3,3,1);
xlabel('x');
ylabel('y');
title('subplot (1,1)');
etc.
It's a matter of space. Matlab will show more ticks if you increase the size of the plot window, and viceversa. You can also reduce the font size in order to fit more ticks on the axes (try with set(gca,'FontSize',5) or any other font size value).