Draw line between two subplots - matlab

I have two two-by-n arrays, representing 2d-points. These two arrays are plotted in the same figure, but in two different subplots. For every point in one of the arrays, there is a corresponding point i the other array. I want to show this correspondance by drawing a line from one of the subplots to the other subplot.
The solutions i have found are something like:
ah=axes('position',[.2,.2,.6,.6],'visible','off'); % <- select your pos...
line([.1,.9],[.1,.9],'parent',ah,'linewidth',5);
This plots a line in the coordinate system given by the axes call. In order for this to work for me i need a way to change coordinate system between the subplots system and the new system. Anybody know how this can be done?
Maybe there is different way of doing this. If so i would love to know.

First you have to convert axes coordinates to figure coordinates. Then you can use ANNOTATION function to draw lines in the figure.
You can use Data space to figure units conversion (ds2nfu) submission on FileExchange.
Here is a code example:
% two 2x5 arrays with random data
a1 = rand(2,5);
a2 = rand(2,5);
% two subplots
subplot(211)
scatter(a1(1,:),a1(2,:))
% Convert axes coordinates to figure coordinates for 1st axes
[xa1 ya1] = ds2nfu(a1(1,:),a1(2,:));
subplot(212)
scatter(a2(1,:),a2(2,:))
% Convert axes coordinates to figure coordinates for 2nd axes
[xa2 ya2] = ds2nfu(a2(1,:),a2(2,:));
% draw the lines
for k=1:numel(xa1)
annotation('line',[xa1(k) xa2(k)],[ya1(k) ya2(k)],'color','r');
end
Make sure your data arrays are equal in size.
Edit: The code above will do data conversion for a current axes. You can also do it for particular axes:
hAx1 = subplot(211);
% ...
[xa1 ya1] = ds2nfu(hAx1, a1(1,:),a1(2,:));

A simple solution is to use the toolbar in the figure window. Just click "insert" and then "Line".

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:

plot multiple 3d lines

I'm trying to plot 2 lines in a single 3D graph. I have 3 coordinate data matrices for each line.
This is my code:
plot3(pathline_x1 , pathline_y1 , pathline_z1,'g');
hold on
plot3(pathline_x1,pathline_y1,pathline_z1,'r');
hold on
From some reason it plots only the last one. Can someone help me plot both lines?
x = [1 2];y=x;
figure;plot(x,y,'r');hold on;plot(x,y,'b');
This will overwrite your line, since x and y are exactly equal.
To see it actually works, plot two different lines:
figure;plot(x,y,'r');hold on;plot(x,y+2,'b');
Note that I have called hold on only once, since it will hold all plots within the figure until you call hold off or open a new figure using figure.

plotting a text file with 4 columns in matlab

I want to plot a text file with 4 columns that first column in longitude,second in latitude, third is depth and forth is amount of displacement in each point.(it's related to a fualt)
-114.903874 41.207504 1.446784 2.323745
I want a plot to show the amount of displacement in each point (like images that we plot with imagesc),unfortunately "imagesc" command doesn't work for it.
how can I plot it?
Thanks for your attention
A simple way would be to use scatter3 and assign your displacements to be the colours. Note that you have to supply a size for this to work - I'm using [] (empty matrix) which will set it to default. If your four sets of values are four vectors of the same size, then it's just something like:
scatter3(lat,lon,depth,[],displacement, 'filled')
Values in displacement will be linearly mapped to the current colormap. 'filled' gives you filled markers rather than open ones (default marker is a circle but can be changed).
You can plot each point using plot3(longitude,latitude,depth). You can color each point according to the displacement in a for loop. The easiest way to do this is create a colormap, e.g. using jet and chosing the color according to the displacement.
figure;
hold on;
cmap = jet(256);
dispRange = [min(displacement),max(displacement)];
for k=1:size(longitude,2)
c = cmap(1+round(size(cmap,1)*(displacement(k)-dispRange(1))/dispRange(2)),:);
plot3(longitude(k),latitude(k),depth(k),'o', ...
'MarkerEdgeColor',c,'MarkerFaceColor',c);
end

grouped scatterhist in subplot in matlab

I am trying to make subplots using the grouped scatterhist function in matlab.
subplot(2,2,1)
scatterhist(x,y,'Group',factor)
subplot(2,2,2)
scatterhist(x,y,'Group',factor)
This makes one normal sized plot of the second subplot. Any ideas?
scatterhist doesn't interact well with subplot, so you have to find ways around that.
Here is a way of doing it with uipanel.
% create two separate figures with the two scatterplots in
h1 = figure
scatterhist(x,y,'Group',factor)
h2 = figure
scatterhist(x,y,'Group',factor)
% create third figure split into two uipanels
h3 = figure
u1 = uipanel('position',[0,0,0.5,1]);
u2 = uipanel('position',[0.5,0,0.5,1);
% get all children from each figure and move to the uipanels
set(get(h1,'Children'),'parent',u1);
set(get(h2,'Children'),'parent',u2);
%close unneeded figures
close(h1,h2)
If you wanted to do a lot of these, you might want to create a function that works out the right position values depending on how many subplots you want in the figure.

MATLAB - How to zoom subplots together?

I have multiple subplots in one figure. The X axis of each plot is the same variable (time). The Y axis on each plot is different (both in what it represents and the magnitude of the data).
I would like a way to zoom in on the time scale on all plots simultaneously. Ideally by using the rectangle zoom tool on one of the plots, and having the other plots change their X limits accordingly. The Y limits should remained unchanged for all of this. Auto fitting the data to fill the plot in the Y direction is acceptable.
(This question is almost identical to Stack Overflow question one Matplotlib/Pyplot: How to zoom subplots together? (except for MATLAB))
Use the built-in linkaxes function as follows:
linkaxes([hAxes1,hAxes2,hAxes3], 'x');
For more advanced linking (not just the x or y axes), use the built-in linkprop function
Use linkaxes as Yair and Amro already suggested. Following is a quick example for your case
ha(1) = subplot(2,1,1); % get the axes handle when you create the subplot
plot([1:10]); % Plot random stuff here as an example
ha(2) = subplot(2,1,2); % get the axes handle when you create the subplot
plot([1:10]+10); % Plot random stuff here as an example
linkaxes(ha, 'x'); % Link all axes in x
You should be able to zoom in all the subplots simultaneously
If there are many subplots, and collecting their axes handle one by one does not seem a clever way to do the job, you can find all the axes handle in the given figure handle by the following commands
figure_handle = figure;
subplot(2,1,1);
plot([1:10]);
subplot(2,1,2);
plot([1:10]+10);
% find all axes handle of type 'axes' and empty tag
all_ha = findobj( figure_handle, 'type', 'axes', 'tag', '' );
linkaxes( all_ha, 'x' );
The first line finds all the objects under figure_handle of type "axes" and empty tag (''). The condition of the empty tag is to exclude the axe handles of legends, whose tag will be legend.
There might be other axes objects in your figure if it's more than just a simple plot. In such case, you need to add more conditions to identify the axes handles of the plots you are interested in.
To link a pair of figures with linkaxes use:
figure;imagesc(data1);
f1h=findobj(gcf,,’type’,’axes’)
figure;imagesc(data2);
f2h=findobj(gcf,,’type’,’axes’)
linkaxes([f1h,f2h],’xy’)