# Adding labels to close points in a ListPlot [duplicate]

I need to add labels to points in a ListPlot. The only problem is that the points can be closely located so if I do it in my usual way it becomes messy.

I would like no label overlaps another not any point in the plot (something like in the figure below or better).

There is some solution that comes close to solving my problem: How to position text labels automatically to not overlap other graphics elements? , but still in proposed solution if several points are close the labels start to overlap! It happens because they draw the label always close to the point.

Here is the code to generate a cluster of close points I need to label:

data = Table[{t, Re[3 Exp[I 5/2 t]] - t, Im[5 Exp[I 5/2 t]]}, {t, 0, 10}];
dataPlot = ListPlot[data[[All, {2, 3}]], PlotStyle -> PointSize -> Large];
labels = Text[Label  #[[1]], 1.1 #[[{2, 3}]]] & /@ data;
Show[dataPlot, Graphics[{Red, labels}],
PlotRange -> 50 {{-1, 1}, {-1, 1}}, AspectRatio -> 1]


which gives the following result:

• How about labeling them in another plane (in 3D)? – xslittlegrass Jun 12 '16 at 16:53
• Have you seen Tooltip? – Edmund Jun 12 '16 at 16:54
• @Edmund Tooltip is not very useful for print version I need finaly – Филипп Цветков Jun 12 '16 at 16:58
• @SimonWoods No! in proposed solution if points are close the labels starts to overlaps! It happens because they draw the label always close to the point. – Филипп Цветков Jun 12 '16 at 17:12
• Could you post code to generate a suitable example plot? It would make it easier for people to test their ideas. – Simon Woods Jun 12 '16 at 17:19

You could plot each data point with a marker that is also its label. Like so

labels = CharacterRange["A", "Z"];
SeedRandom[42];
data = List /@ Transpose[Table[RandomSample[Range[26]], 2]]

ListPlot[data, PlotStyle -> Black, PlotMarkers -> labels]


### Note

Each data point must be wrapped in a list. That is,

{{{14, 3}}, {{21, 25}}, ..., {{26, 12}}, {{12, 4}}}


not the usual

{{14, 3}, {21, 25}, ..., {26, 12}, {12, 4}}


### Update

If you need supply long annotations, consider making the annotations in legends associated with the point markers. For example,

longForm = # <> " annotation" & /@ labels;
ListPlot[data, PlotStyle -> Black, PlotMarkers -> labels, PlotLegends -> longForm]


• Well.. It is good idea, but I need to add real labels, which are sometimes longer than one symbol – Филипп Цветков Jun 12 '16 at 17:43
• @ФилиппЦветков. I didn't use symbols; I used strings. They can be any length and contain spaces and punctuation in them. – m_goldberg Jun 12 '16 at 17:52
• @ФилиппЦветков. I have added another plot showing how I would handle long labels without cluttering up the main plot – m_goldberg Jun 12 '16 at 18:15
colors = ColorData[1, "ColorList"][[;; Length@data]];

Deploy@DynamicModule[{pt = ({##2} & @@@ data), pt2 =(4 {##2} & @@@ data),
lbls = Module[{i = 1}, Framed["Label" <> ToString[#],
FrameStyle -> colors[[i++]]] & @@@ data]},
ListPlot[List /@ pt, PlotStyle -> PointSize[Large],
PlotRange -> 50 {{-1, 1}, {-1, 1}}, AspectRatio -> 1,
Epilog -> (Dynamic[{colors[[#]], Line[{pt2[[#]], pt[[#]]}],
Locator[Dynamic@pt2[[#]], Style[lbls[[#]], colors[[#]], "Panel"]]} & /@
Range[Length@pt]])]]


After manual adjustment of labels using the locators:

• ... couldn't figure out how to set the initial positions of labels to minimize the manual adjustments. – kglr Jun 12 '16 at 20:52
• Very nice! Almost. It is even better when it is possible to move labels to get nice final figure. Still it will take a lot of time since I have about 100 points. Maybe it is possible to add some "physical interactions" between labels so they "drop down"? – Филипп Цветков Jun 12 '16 at 22:24