9
$\begingroup$

When I plot a Piecewise function, I like to put the function name above each part of the plot. I could not find a way to use Callout. So now I use Text to manually put the function name above each part of the curve. Here is MWE

ClearAll[x,h];
h[x_] := Piecewise[{{Exp[x],x < -1}, {1 - x^2, -1 < x < 1}, {Sin[Pi x], x > 1}}];
Plot[h[x], {x, -3, 3}]

Mathematica graphics

Obviously, putting the Callout inside Piecewise does not work.

h[x_] := 
  Piecewise[
    {{Callout[Exp[x], "Exp[x]"], x < -1}, 
     {1 - x^2, -1 < x < 1}, 
     {Sin[Pi x], x > 1}}];

So now I do the following, which requires few trials and errors to get the labels in the right place.

h[x_] := Piecewise[{{Sin[Pi x],x > 1}, {1 - x^2, -1 < x < 1}, {Exp[x], x < -1}}];
Plot[h[x], {x, -3, 3},
  PlotRange -> {Automatic, {-1.2, 1.2}},
  PlotStyle -> Red,
  BaseStyle -> 12,
  Epilog -> 
    {Text["Exp[x]", {-2, .3}], 
     Text["1-x^2", {.4, 1.1}],
     Text["Sin[Pi x]", {1.7, .3}]}]

Mathematica graphics

My question is: Is there a trick to use Callout when plotting Piecewise function?

V 12 on windows

$\endgroup$

3 Answers 3

8
$\begingroup$
Clear["Global`*"]

h[x_] := Piecewise[{{Exp[x], 
     x < -1}, {1 - x^2, -1 < x < 1}, {Sin[Pi x], x > 1}}];

plotRng = {-3, 3};

EDIT: Extracting intervals

intervals = {Cases[h[x][[1, All, -1]], _?NumericQ, 2], plotRng} // 
    Flatten // Union // Partition[#, 2, 1] &;

Show[
 Plot[
    Callout[h[x], 
     Simplify[h[x], Less @@ Insert[#, x, 2]] //
       TraditionalForm // ToString,
     Above,
     Appearance -> None,
     Background -> None],
    {x, Sequence @@ #},
    PlotStyle -> Red] & /@
  intervals,
 PlotRange -> {plotRng, Automatic}]

enter image description here

$\endgroup$
1
  • $\begingroup$ +1. You can find the endpoints automatically like this: endpoints = Cases[ pl, Line[coords_] :> ({First@#, Last@#} &@Sort[First /@ coords]), Infinity]; where pl is the original plot. $\endgroup$
    – C. E.
    Nov 3, 2019 at 20:34
8
$\begingroup$

EDIT

The code below doesn't work anymore - see the comments

END OF THE EDIT

It is possible to nest several Callout:

   ClearAll[x, h];
    h[x_] := Piecewise[{{Exp[x], 
         x < -1}, {1 - x^2, -1 < x < 1}, {Sin[Pi x], x > 1}}];
    Plot[
     Callout[Callout[Callout[h[x], "Exp[x]", -2], "Sin[Pi x]", 2], 
      "1-x^2", {0.3, Above}], {x, -3, 3}]  

enter image description here

Seen in this video of Wolfram Technology Conference 2018.
There is a notebook attached to this video - see Section "parametric Curve Labeling"

$\endgroup$
3
  • 1
    $\begingroup$ It seems that the nested Callout does not work with Mathematica 12.1. $\endgroup$
    – E. MacRae
    Jun 1, 2020 at 15:22
  • $\begingroup$ confirming, for Linux $\endgroup$ Jun 1, 2020 at 16:19
  • $\begingroup$ I have just tested the code above with 12.1 on Windows 7. I confirm It doesn't work anymore. $\endgroup$
    – andre314
    Jun 1, 2020 at 16:33
1
$\begingroup$
ClearAll[pwToCE]
pwToCE[f_] := ConditionalExpression @@@ f[#][[1]] &

positions = {-2, {.5, Above}, {1.5, Below}};

Plot[Evaluate@MapThread[Callout[#, #[[1]], #2] &, {pwToCE[h][x], positions}],
   {x, -3, 3}, PlotStyle -> ColorData[97][1]]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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