9
$\begingroup$

I have a point {0,0} which I call A, and a point {2,1} which I call B. I want to make an image that looks like the one below.

enter image description here

When I resize the image I want the text labels to follow the points, so that the distances from labels to the points remain the same.

I tried with the following code

p0 = Point[{0, 0}];
p1 = Point[{2, 1}];
Graphics[{{p0, Text["A", Offset[{-5, -5}]]}, {p1, 
   Text["B", Offset[{160, 80}]]}}, ImageSize -> {200, 100}]

but as you can see, while the A label seems to be glued to p0 the B label is not glued to the p1.

enter image description here

So my question is how do you glue text labels to points so that when points are moved the text labels follow along.

$\endgroup$
9
$\begingroup$

First of all your Offset specification is strange, I'd make it Offset[{-5, -5}, {2, 1}], right?

Then, you can use GraphicsGroup to treat it as a single item for the purpose of interactive editing:

p0 = Point[{0, 0}];
p1 = Point[{2, 1}];
Graphics[{
  GraphicsGroup @ {p0, Text["A", Offset[{-5, -5}, {0, 0}]]}, 
  GraphicsGroup @ {p1, Text["B", Offset[{-5, -5}, {2, 1}]]}
}, ImageSize -> {200, 100}]

enter image description here

$\endgroup$
  • 2
    $\begingroup$ A formulation without Offset: Graphics[GraphicsGroup /@ {{p0, Text["A", {0, 0}, {1, 1}]}, {p1, Text["B", {2, 1}, {-2, -1}]}}, ImageSize -> {200, 100}] $\endgroup$ – Mr.Wizard Jul 10 at 15:23
4
$\begingroup$

This is just a little remark. Using Kuba's answer above we can define a help function

namedPoint[pt_, ptName_, ptSize_: Medium, offset__: {-5, -5}] := 
 Module[{},
  GraphicsGroup[{{PointSize[ptSize], Point[pt]}, 
    Text[ptName, Offset[offset, pt]]}]
    ]

and do simple calls like

Graphics[{namedPoint[{0, 0}, "O"], namedPoint[{1, 1}, "A"], 
  namedPoint[{2, -1}, "B"]}, ImageSize -> 100]

which gives and image like this

<code>enter image description here</code>

$\endgroup$
  • $\begingroup$ The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments". $\endgroup$ – Bob Ueland Jul 11 at 8:52
4
$\begingroup$

Another possibility is to use Callout inside of ListPlot:

ListPlot[{Callout[p0[[1]], "A"], Callout[p1[[1]],"B"]}]

enter image description here

$\endgroup$
  • $\begingroup$ Callout is only available in Mathematica 11 and later. $\endgroup$ – Bob Ueland Jul 10 at 15:31
  • $\begingroup$ I am not 100% it was a requirement but you can't move the label and the point together. $\endgroup$ – Kuba Jul 11 at 8:12
0
$\begingroup$

Recenter your coordinate system and rescale the text coordinates

{{-1, -0.5}, {1, .5}} //
Graphics[{
    Point /@ #,
    Text[#1, .9 #2] &~MapThread~{{"A", "B"}, #}
    }]&
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.