Matlab - Plot difference between two graphs in specific points - matlab

I have two graphs, one is the exact graph of a solution, the other is a numerical approach. I have 4 specific points in my figure (t=0.25,0.5,0.75,1), where I want to illustrate the difference between the two graphs with a straight line. I found the errorbars function but i don't see any use there. Hope you can help me!
Edit:
this is the example figure:
t = [0:0.25:1];
y = t.*4;
x = t.^2+3;
plot(t,y,t,x)
I have 4 points now, t=0.25; t=0.5; t=0.75; t=1; At this points, I just want a vertical line between the two plots. I already have tried this: plot([t(1),y(1)],[t(1),x(1)])
but it just creates a line over the whole figure.

✶ It seems that you're not using hold on before using plot command the second time because otherwise you'd have got the desired result (which is actually not a correct way of plotting a vertical line).
✶ You're mixing up the values of x and y for plot(x,y). To plot a vertical line, it should be used like this: plot([x,x], [y1,y2])
For your case, you may not notice the difference between plot([t(1),y(1)],[t(1),x(1)]) (which is incorrect) and plot([t(1),t(1)],[x(1),y(1)]) (which is correct) because it is by chance that the values are same. Plot it for some other points and you'll realize the difference.
Fixed Code:
t = [0:0.25:1];
y = t.*4;
x = t.^2+3;
plot(t,y,t,x)
hold on
plot([t(1) t(1)],[x(1) y(1)])
% You have 't' on your horizontal axis and 'x'and 'y' values on the vertical axis
axis equal % just for better visualization
Output:

Related

Multiple vertical histograms plot in matlab

Is it possible to make multiple vertical histograms plot in Matlab into one? Much like the excel sheet enclosed ( https://drive.google.com/file/d/1H_mbyrIoln3XrnK1hLajnVNBKn13y_np/view?usp=sharing )
I want to make a plot of many vertical histogram plots into one figure, by importing excel-files, where on the y axis it has the elevation, the x axis the distance between the histogram vertical lines and the length of the histogram bars is the values in the excel sheet. The vertical height of each bar is 5.
Is this even possible? I have to put in a number of conditions for Matlab to know where to plot, but could some one show me the basic methodology?
Help would be very much appreciated!
The problem is that the parent of a Baseline object is the Axis, which prevents us from doing something like
barh(bins1,counts1,'Basevalue',baseline1); hold on;
barh(bins2,counts2,'Basevalue',baseline2); hold off;
because the plots will automatically share the second baseline value set. There might be a workaround for this that I do not know of, so I invite anybody who knows it to show me how its done.
For now, I was able to sort-of replicate the plot you posted a picture of in a much less elegant way. I will post code below, but before I do, I would like to argue against the use of a plot like this. Why? Because I think it is confusing, as the x-axis both relates to the plot number as well as the bin count numbers. You are in fact trying to display a 3-D data set, the three dimensions being bins, bin counts, and 'histogram number'. A plethora of methods exist for displaying 3-D data, and a series of 2-D histograms may not be the best way to go.
That being said, here is a code that more-or-less creates the picture above, as promised. Any changes you may want to make will be more cumbersome than usual :-)
testData = randn(10000,1); % Generate some data
[counts,bins] = hist(testData); % Bin the data
% First histogram
baseline1 = 0;
p1=subplot(1,3,1); barh(bins,counts,'BaseValue',baseline1);
xticks(baseline1); xticklabels({0}); % Graph number on x axis at baseline (0)
box off; % Remove box on right side of plot
ylabel('Property');
% Second histogram
baseline2 = max(counts)*1.2;
sepdist = baseline2-baseline1; % Distance that separates two baselines
counts2 = baseline2 + counts;
p2=subplot(1,3,2); barh(bins,counts2,'BaseValue',baseline2)
xticks(baseline2); xticklabels({1}); % Graph number on x axis at baseline
box off;
Y=gca; Y.YAxis.Visible='off';
p1p=p1.Position; p2p=p2.Position;
p2p(1)=p1p(1)+p1p(3); p2.Position=p2p; % Move subplot so they touch
% Third histogram
baseline3 = baseline2 + sepdist;
counts3 = baseline3+counts;
p3=subplot(1,3,3); barh(bins,counts3,'BaseValue',baseline3)
xticks(baseline3); xticklabels({2});
Y=gca; Y.YAxis.Visible='off';
box off
p3p=p3.Position;
p3p(1)=p2p(1)+p2p(3); p3.Position=p3p;
% Add x-label when you are done:
xl=xlabel('Test xlabel'); xl.Units='normalized';
% Fiddle around with xl.Position(1) until you find a good centering:
xl.Position(1) = -0.49;
Result:

MATLAB: Two different y-axis limits for Multiple plots on same graph

I need to plot two plots on same figure in MATLAB.
The maximum and minimum values in both the data samples have large variation, which I am unable to plot by taking same y-axis limits.
I do not wish to use two scales as explained in other Overlaying two axes in a Matlab plot but need to use a single y-axis and get the solution.
I tried the code:
x_axis_X = 1:length(S);
y_axis_Y = 1:length(N);
ylim([-1204200 -1841.6])
set(gcf,'color','w');
plot(x_axis_X, S,'o-', y_axis_Y, N, 'x-');
The result is as shown in the plot where one data sample is plotted without proper y-axis range.
The y limits for first data sample is -1204200 to -1841.6 and for the second it is -489429345.5 to -10408189.43.
How should be the ylim defined to fit both plots in the same figure?
I appreciate your inputs. Thank you.
In older versions of MATLAB use the function plotyy. In more recent versions of MATLAB use yyaxis. The following is the example from the documentation:
x = linspace(0,10);
y = sin(3*x);
yyaxis left
plot(x,y)
z = sin(3*x).*exp(0.5*x);
yyaxis right
plot(x,z)
ylim([-150 150])
I tried the idea of scaling one dataset so that it has a similar magnitude as the other data set. Here, I multiplied one dataset by 100 (or any suitable scaling parameter), and then it will be similar in size to the other data set. In order to clearly mention which data has been scaled in the graph I used the legend.
plot(x,data1,x,100*data2)
legend('data1','100*data2','location','southeast')
Thank you.
Scaling is not the best option, as you may need to work with the data later. Also does not work if for instance, you need a log scale.
Matlab has a few ways to deal it with. I particularly like to use a new axes in the figure, as i have done in the example below.
Just in case, you also found this answer in a simple google search!
Code:
a=1:10;
b=(10:-1:1)*100;
x=1:10;
hold on
plot(x,a,'b')
pax1=get(gca,'Position'); %get axis position
ax2 = axes('Position',pax1); %create a new axis
plot(ax2,x,b,'r') %plot new data
set(ax2, 'Yaxislocation','right',...
'color','none') % set it transparent and to the right

Best way to plot marks on a line in Matlab

This question is quite basic, but I am looking for the best way to do this.
For a plotted line in matlab, how can a few points on the line be marked. I know it is possible to plot directly using marks. But, in case the line has been plotted and the marks are just to differentiate the plots. Instead of selecting a few points and plotting the second time. An example is shown in this figure below
Right after creating the initial plot you can use the command 'hold on' to keep that plot 'live' and then replot the points as markers. For example:
x=1:10;
y=2*x+4;
plot(x,y)
hold on
plot(x,y,'+')
You can use '*', '.' or any other marker instead of '+'.
If you want the markers to be evenly spaced (and your data is not ,originally) you may create an evenly spaced x vector and then, assuming your plot is not too extreme, interpolate the y values and add just the points. For example:
x=[1,1.5,2,2.3,3,4,4.8,5,6.1,6,7,8,9,10];
y=2*x.^2+4;
plot(x,y)
hold on
x_lin=linspace(min(x),max(x),20);
y_lin=interp1(x,y,x_lin,'linear');
plot(x_lin,y_lin,'+')
hold off
With the following result:
If 'linear' doesn't give a good enough result you can try other interpolation methods like 'cubic', 'spline'...
If you don't want to "add" the marked points in a second moment (but I don't think you will have some advantage), consider to
A) use two plot instructions, separating the array of points "to be marked" using
C = setdiff(A,B)
alternatively
B) plot every point in a for cycle with counter i under a condition
%not tested solution
c1 = '.r' %red point, if they are near they seems a line
c2 = '*b' %blue marker
if (marker_condition == true)
plot(x(i), y(i), c2)
else
plot(x(i), y(i), c1)
end

Draw evenly-spaced height lines of a function in MATLAB

I would like to draw height lines of a function (represented by matrices, of course), using MATLAB.
I'm familiar with contour, but contour draws lines at even-spaced heights, while I would like to see lines (with height labels), in constant distance from one another when plotted.
This means that if a function grows rapidly in one area, I won't get a plot with dense height lines, but only a few lines, at evenly spaced distances.
I tried to find such an option in the contour help page, but couldn't see anything. Is there a built in function which does it?
There is no built-in function to do this (to my knowledge). You have to realize that in the general case you can't have lines that both represent iso-values and that are spaced with a fixed distance. This is only possible with plots that have special scaling properties, and again, this is not the general case.
This being said, you can imagine to approach your desired plot by using the syntax in which you specify the levels to plots:
...
contour(Z,v) draws a contour plot of matrix Z with contour lines at the data values specified in the monotonically increasing vector v.
...
So all you need is the good vector v of height values. For this we can take the classical Matlab exemple:
[X,Y,Z] = peaks;
contour(X,Y,Z,10);
axis equal
colorbar
and transform it in:
[X,Y,Z] = peaks;
[~, I] = sort(Z(:));
v = Z(I(round(linspace(1, numel(Z),10))));
contour(X,Y,Z,v);
axis equal
colorbar
The result may not be as nice as what you expected, but this is the best I can think of given that what you ask is, again, not possible.
Best,
One thing you could do is, instead of plotting the contours at equally spaces levels (this is what happens when you pass an integer to contour), to plot the contours at fixed percentiles of your data (this requires passing a vector of levels to contour):
Z = peaks(100); % generate some pretty data
nlevel = 30;
subplot(121)
contour(Z, nlevel) % spaced equally between min(Z(:)) and max(Z(:))
title('Contours at fixed height')
subplot(122)
levels = prctile(Z(:), linspace(0, 100, nlevel));
contour(Z, levels); % at given levels
title('Contours at fixed percentiles')
Result:
For the right figure, the lines have somewhat equal spacing for most of the image. Note that the spacing is only approximately equal, and it is impossible to get the equal spacing over the complete image, except in some trivial cases.

Making an accurate colorbar for a simple plot

I am trying to make a simple plot (for this example doing a plot of y=x^2 will suffice) where I want to set the colors of the points based on their magnitude given some colormap.
Following along my simple example say I had:
x = 1:10;
y = x.^2;
Use gscatter(x,y,jet(10)); legend hide; colorbar which produces a plot with the points colored but the colorbar does not agree with the colored values. (Can't post picture as this is my first post). Using a caxis([1,100]) command gives the right range but the colors are still off.
So I have two questions:
(1) How can I fix the colors to fit to a colorbar given a range? In my real data, I am looking at values that range from -50 to 50 in some instances and have many more data points.
(2) I want to create a different plot with the same points (but on different axes) and I want the colors of each point on this new plot to have the same colors as their counterparts in the previous plot. How can I, programmatically, extract the color from each point so I can plot it on two different sets of axes?
I would just move the points into a matrix and do an imagesc() command but they aren't spaced as integers or equally so simple scaling wouldn't work either.
Thanks for any help!
Regarding you first question, you need to interpolate the y values into a linear index to the colormap. Something like:
x = 1:10;
y = x.^4;
csize = 128;
cmap = jet(csize);
ind = interp1(linspace(min(y),max(y),csize),1:csize,y,'nearest');
scatter(x,y,14,cmap(ind,:),'filled')
colorbar
caxis([min(y) max(y)])
Using interp1 in this case is an overkill; you could calculate it directly. However, I think in this way it is clearer.
I think it also answers your 2nd question, since you have the index of the color of each data point, so you can use it again in the same way.