Annotations with arrows for scatter plot

I have a scatter plot and would like to add labels with arrows for each data point (similar to the example below). I have a cellstring vector called ' labelc' with data labels of the same length as my x and y data vectors. I tried to use the annotation function in matlab to create the labels as follows...
a = annotation('textarrow',x,y,'String',labelc);
...but got an error message:
Error using annotation (line 121) unknown argument
Does anybody know how to achieve this?

 Accepted Answer

*‘... with data labels of the same length as my x and y data vectors.’
That could be the problem. The documentation does not appear to support array arguments for them. See if putting the annotation calls in a loop, with one value for each ‘x’, ‘y’, and ‘labelc’ in every iteration works:
for k = 1:...
a = annotation('textarrow',x(k),y(k),'String',labelc(k));
end
Make necessary changes to be certain ‘labelc’ is addressed correctly so it displays correctly.
(I am currently running a long optimization, and cannot test this approach just now.)

14 Comments

Thanks for the suggestion. Unfortunately the error message remains the same.
My pleasure.
We have only one line of your code, and we do not know the MATLAB release you are using.
We need to see more of your code, and to know what the data you use in your annotation call are (double arrays, cell arrays, or something else).
I'm using Matlab R2017a.
The standard way of annotation with arrow according to matlab documentation is
a = annotation('textarrow',x,y,'String','string name');
This code seems to work fine for labeling a single point, but not when is has to be done for multiple points.
Instead of 'string name' I put labelc which is the name of a vector in cell array format and which has the same length as vectors x and y.
I hope this clarifies the inputs I'm using.
I understand. As I mentioned in my original Answer, ‘the documentation does not appear to support array arguments’. That’s the reason I suggested the loop.
That ‘labelc’ is a cell array is immensely helpful. This works for getting the labels to pring:
for k = 1:...
annotation('textarrow',x,y,'String',labelc{k});
end
I leave for you to create the correct ‘x’ and ‘y’ vectors for each iteration.
I changed the brackets as per your suggestion but unfortunately the outcome is the same error message.
I know that using ‘labelc{k}’ is not the problem. I have no idea what the problem could be.
I will delete my Answer in a few minutes.
Florian, can you show a small segment of the modified code you're using along with the full text (everything in red) of the error message, so we can make sure everyone's on the same page?
Hi Steve, below is the code and attached is a screen capture with the resulting plot, error message and input variables highlighted in the workspace.
figure('Position', [300 300 900 800]) % display phi vs KH with MICP modal distribution
scatter(phi,KH,[],micpdist,'filled')
xlabel('porosity')
ylabel('permeability')
title('LAPA wells 50-74-100 porosity vs permeability vs MICP pore distribution')
set(gca, 'yscale','log')
grid on
xlim([0 0.25])
colorbar
colormap(micpcode)
C = colorbar;
set(get(C,'YLabel'),'String','pore throat type (0-unimodal == 2-bimodal == 1-unclear')
for k = 1:length(phi)...
a(k) = annotation('textarrow',phi(k),KH(k),'String',labelc{k});
end
You are using the wrong syntax. phi(k) and KH(k) are both single values when they should be pairs. I believe the syntax is something like:
a = annotation('textarrow',[x1 x2],[y1 y2],'String','mystring')
No, Jonas, that's incorrect. x and y are not pairs, but they must be unique values to specify the position in the scatter plot. See:
https://se.mathworks.com/help/matlab/ref/annotation.html
Look at the first example in the doc
x = [0.3 0.5];
y = [0.6 0.5];
annotation('textarrow',x,y,'String','y = x ')
two values constitutes a pair. How do you think the function determines the length of the arrow, by magic?
Jonas is correct.
I sort of got this to work, although it is difficult for me to understand how to normalise the annotation coordinates in order to plot them correctly. It would be nice if there was a documentation section demonstrating it, or preferably a function that would do that calculation.
Run this for an example. Experiment with this to get the result you want:
x = 1:5;
y = randi(9,size(x));
labelc = compose('Point %d', x)
figure
scatter(x, y, y*10)
axis([0 10 0 10])
pxy = get(gca, 'Position');
px = pxy([1 3]);
py = pxy([2 4]);
lx = xlim;
ly = ylim;
dlx = diff(lx);
dly = diff(ly);
for k = 1:numel(x)
Q1 = [((x(k)-lx(1))/dlx+px(1)).*[0.7, 0.8], ((y(k)-ly(1))/dlx+py(1)).*[0.7, 0.8]]
annotation('textarrow', Q1(1:2), Q1(3:4), 'String',labelc{k});
end
This should provide a start point. I encourage others to add more definitive Answers. I will delete this Answer in a few days.
Thanks to Star Strider for the answer - and thanks Jonas for pointing out the pair: you were absolutely correct!

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!