I can draw two points in space and place arrows at them:
plot(1,1,'o','MarkerEdgeColor','k','MarkerFaceColor','k','MarkerSize',5,'LineWidth',1.5); hold on;
plot(2,1,'o','MarkerEdgeColor','k','MarkerFaceColor','k','MarkerSize',5,'LineWidth',1.5); hold on;
vec1=zeros(1,3); vec2=zeros(1,3); col1=zeros(1,3); col2=zeros(1,3);
vec1=[0.98996547 0.00000000 0.14130945];
vec2=[0.00000000 0.70710678 -0.70710678];
col1= [abs(vec1(1,1)) abs(vec1(1,2)) abs(vec1(1,3))];
col2= [abs(vec2(1,1)) abs(vec2(1,2)) abs(vec2(1,3))];
scalef=0.4;
quiver3(1,1,0,vec1(1,1)*scalef,vec1(1,2)*scalef,vec1(1,3)*scalef,'AutoScale','off', 'MaxHeadSize',5,'LineWidth',5,'Color',col1); hold on;
quiver3(2,1,0,vec2(1,1)*scalef,vec2(1,2)*scalef,vec2(1,3)*scalef,'AutoScale','off','MaxHeadSize',5,'LineWidth',5,'Color',col2); hold on;
view(20,20);
hold off;
The beginning of each arrow is the black point. How can I move the beginning of the arrow before the point so that the visual effect is better? Stated otherwise how can I place the points in the body of the arrow?
Related
I have (x,y,z) data points of many solid objects which are not aligned to the global axis. The data points are available only for the end part of solid objects, not for middle part due to experimental constraints. My task is to first align the center line of each solid object to the global axis and then compare these solids. Finding the center line of both ends separately is also okay to me. I read about finding the principal axis using the eigenvector, which I did but it is not finding centerline.
How do I find the longitudinal centerline of this kind of object?
Magenta Largest eigenvector of whole
Red and yellow (Largest eigenvector of separate part)
r=cov(data); data=DTPT (86043×3)
[vec,val]=eig(r);
plot3(data(:,1),data(:,2),data(:,3),'.','markersize',1)
mu=mean(data);
d = sqrt(diag(val));
hold on;
quiver3(mu(1),mu(2),mu(3),2*vec(1,3),2*vec(2,3),2*vec(3,3), d(3), 'm','LineWidth',5);
quiver3(mu(1),mu(2),mu(3),-2*vec(1,3),-2*vec(2,3),-2*vec(3,3), d(3), 'm', 'LineWidth',5);
hold off;
indDT=1:37768;
data1=data(indDT,:);
[v,l]=eig(cov(data1));
mu=mean(data1);
d = sqrt(diag(l));
hold on;
quiver3(mu(1),mu(2),mu(3),3*v(1,3),3*v(2,3),3*v(3,3),d(3), 'r', 'LineWidth',5);
quiver3(mu(1),mu(2),mu(3),-3*v(1,3),-3*v(2,3),-3*v(3,3),d(3),'r','LineWidth',5);
hold off;
indPT=37769:86043;
data2=data(indPT,:);
[v,l]=eig(cov(data2));
mu=mean(data2);
d = sqrt(diag(l));
hold on;
quiver3(mu(1),mu(2),mu(3),3*v(1,3),3*v(2,3),3*v(3,3),d(3), 'y','LineWidth',5);
quiver3(mu(1),mu(2),mu(3),-3*v(1,3),-3*v(2,3),-3*v(3,3),d(3),'y','LineWidth',5);
hold off;
Here are the data and the MATLAB figure.
I'm trying to individually link both y-axes in an yyaxis subplot. So far I'm only linking the right y-axes in the given code by calling linkaxes(g), where g are the axes handles. How can I also get the left y-axes linked to one another?
Thanks.
g(1) = subplot(2,1,1);
hold on;
yyaxis left;
plot(rand(10,1));
yyaxis right;
plot(2*rand(10,1));
hold off;
g(2) = subplot(2,1,2);
hold on;
yyaxis left;
plot(2*rand(10,1));
yyaxis right;
linkaxes(g);
plot(rand(10,1));
hold off;
An Axes object has the read-only property YAxisLocation that is set upon every call to yyaxis and remembers the last axis that was in use. When you type linkaxes(g) it simply takes the right axis because that the last one you set. To see that you can run this code for the first axes:
g(1) = subplot(2,1,1);
hold on;
yyaxis right;
plot(2*rand(10,1));
yyaxis left;
plot(rand(10,1));
hold off;
and see how this time the left top axis is linked to the right bottom axis.
If you want to link both axes you just need to add this lines at the end of your code to refer again to the left axis:
yyaxis(g(1),'left')
yyaxis(g(2),'left')
linkaxes(g);
Alternatively, you could grab the handles to the numeric rulers, and use linkprop (without any call to linkaxes):
Y = get(g,'YAxis');
Y = [Y{:}];
linkprop(Y(1,:),'Limits')
linkprop(Y(2,:),'Limits')
You should add this after all axis are created, so all the handles will be assigned already.
i have a question regarding legend for movies.
This is my code:
fig = figure();
for i = 1: 70000
plot(signal1)
hold on;
plot([i,i],[-5,5])
plot(signal2,'r')
hold off;
title('\fontsize{14} my data');
legend('signal1','signal2');
axis tight;
f(i) = getframe(fig);
end
The legend shows the same colors for the first two things I plot. if I plot more it works for the other plots. Is there a trick I don't know?
The strings defined in the legend command are assigned in order of the plots being generated. This means that your first string 'signal1' is assigned to the plot for signal1 and the second string 'signal2' is assigned to the vertical line.
You have two possibilities to fix this problem.
Execute plot for the vertical line after the plot for the two signals.
Use handles to the plots to assign the legends directly.
Here is an example of changing the order:
plot(signal1)
hold on;
plot(signal2,'r')
plot([i,i],[-5,5],'k')
hold off;
legend('signal1','signal2');
Here is an example that uses handles (sp1 and sp2):
sp1 = plot(signal1)
hold on;
plot([i,i],[-5,5],'k')
sp2 = plot(signal2,'r')
hold off;
title('\fontsize{14} my data');
legend([sp1,sp2],'signal1','signal2');
It should have a simple answer which I am missing somehow.
I want to plot only the data points in the x axes. The other points makes things more confusing.
Here is my code:
figure(6);
grid on;
hold on;
colorVec = hsv(length(crl));
for i = 1:(length(crl)-1)
plot(dc,pathLoadMatrix(i,:),'Color',colorVec(i,:),'linewidth',2, 'marker','o');
end
legend('Crl 10%', 'Crl 20%', 'Crl 30%', 'Crl 40%', 'Crl 50%');
xlabel('No of DC');
ylabel('Primary Path Load');
hold off;
Try this: set( gca(), 'xtick', [2:6] )
An answer must be at least 30 characters, so this is filler text.
I am having trouble matching my graph with my axis. The first two plots work and the second two do not. I am trying to plot Temperature versus Pressure for two Argo floats and then Salinity versus Pressure. Here is my code:
% First Plot
subplot(221);
plot(float1winter.T,float1winter.P,'b');
hold on;
plot(float1summer.T,float1summer.P,'r');
hold on;
tempAdiff = abs(float1summer.T-float1winter.T)
plot(tempAdiff,float1summer.P,'--k');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901440 Temp Profiles');
legend(['float1winter','float1summer','tempAdiff'],{'11-29-2013','07-01-2013','Temperature Difference'},'location','southwest');
xlabel('Temperature (°C)');
ylabel('Pressure');
shg;
% Second Plot
subplot(222);
plot(float2winter.S,float2winter.P,'m');
hold on;
plot(float2summer.S,float2summer.P,'c');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901440 Salinity Profiles');
legend(['float2winter','float2summer'],{'11-29-2013','06-02-2013'},'location','southwest');
xlabel('Salinity (psu)');
ylabel('Presure');
shg;
% Third Plot
subplot(223);
% Matrix demensions did not agree bewteen winter and summer profiles. The summer profile was 71 x 2 and the winter was 70 x 2. I tried "reshape"
% and that didn't work. So I changed the vector of float3summer.T to
% float3bsummer.T with an array of 70 x 2
float3bsummer.T = float3summer.T(1:70,1:2);
float3bsummer.P = float3summer.P(1:70,1:2);
plot(float3winter.T,float3winter.P,'Linewidth',1,'color','blue');
hold on;
plot(float3bsummer.T,float3bsummer.P,'Linewidth',1,'color','red');
hold on;
tempdiff = abs(float3bsummer.T-float3winter.T)
plot(tempdiff,float3bsummer.P,'--k');
hold on;
set(gca,'ydir','reverse'); % this line reverses the y-axis so that depth increases downward
title('Argo Float #1901415 Tempearture Profiles');
hold on;
summerfloat = plot(float3bsummer.T,float3bsummer.P,'r');
legend(['float3winter.T','summerfloat','tempdiff'],{'12-03-2013','07-03-2013','Temp Diff'},'location','southeast');
xlabel('Temperature (°C)');
ylabel('Pressure');
axis ([-1,4,0,2000]);
shg;
% Fourth Plot
subplot(224);
plot(float3winter.S,float3winter.P,'g');
% Changed matrix dimensions for Salinity of Summer
float3bsummer.S = float3summer.S(1:70,1:2);
float3bsummer.P = float3summer.P(1:70,1:2);
plot(float3bsummer.S,float3bsummer.P,'.b');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901415 Salinity Profiles');
h4 = plot(float3winter.S,float3winter.P,'g');
hold on;
h5 = plot(float3bsummer.S,float3bsummer.P,'.b');
hold on;
legend(['float3winter','float3bsummer.T'],{'12-03-2013','07-03-2013'},'location','southwest');
xlabel('Salinity (psu)');
ylabel('Pressure');
axis ([33.8,34.8,0,2000]);
shg;
% Save File to Desktop
set(gcf,'color','w');
saveas(gcf,'~/Desktop/hw1_figure1.pdf','pdf');![enter image description here][1]
I guess that you're trying to associate the set of strings for your legend, {'11-29-2013','07-01-2013','Temperature Difference'}, with the plots made from the variables ['float1winter','float1summer','tempAdiff'].
However, this isn't how legend works. MATLAB has no way of associating the plot produced by plot(float1winter.T,float1winter.P,'b'); to the string float1winter. If you want to specify which plots go with which legend entries, you need to pass the object handles of the plots to legend, which is easiest done by returning the handles when you plot originally:
h(1) = plot(float1winter.T,float1winter.P,'b');
hold on;
h(2) = plot(float1summer.T,float1summer.P,'r');
h(3) = plot(tempAdiff,float1summer.P,'--k');
legend(h,{'11-29-2013','07-01-2013','Temperature Difference'});
Side note: you only need to call hold on once per axis - so once for each subplot but not after every plot call.
Alternatively, you can not give handles at all; legend will assign the text to the plots in the order that they were plotted:
legend({'11-29-2013','07-01-2013','Temperature Difference'})
Understanding graphics handles allows you a lot more control over plots, especially if you might want to make small adjustments to them. For example, if I decide that I want the first plot to be green rather than blue, then I can just do:
set(h(1),'Color','g');
This will change the plot color and the legend changes to match automagically. To see a list of all the properties of an object, use get with only the handle. You can set more than one property at a time. For example:
get(h(1))
set(h(1),'DisplayName','Winter','LineWidth',3,'Marker','x')