7

I created the following plot using Mathematica:

Mathematica plot

(* defining functions *)
msp[h_, a_, b_, c_] := 
   Piecewise[{{c + b*(1.5*h/a - 0.5*(h/a)^3), h <= a}, {0, h == 0}}, b + c];
mex[h_, a_, b_, c_] := Piecewise[{{c + b*(1 - Exp[(-3*h)/a]), h != 0}}, 0];
mga[h_, a_, b_, c_] := Piecewise[{{c + b*(1 - Exp[(-(3*h)^2)/a^2]), 0 < h}}, 0];

(* plot *)
Show[Plot[{msp[x, 2, 3, 1], mex[x, 2, 3, 1], mga[x, 2, 3, 1]}, {x, 0, 2.5},
   PlotRange -> {{0, 2.5}, {0, 5}}], ImageSize -> {500, 400}]

I would like to mark the y axis from 0 to 1 and the x axis from 0 to 2 using curly braces like it is done here (E(x)):

Example

Is it possible to do this with Mathematica?

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
2dpc
  • 173
  • 5

1 Answers1

16

The comments seemed to have covered most of the question, but the specific issue of how to best use a curly brace to label an interval in a plot may deserve a more detailed answer. It seems to me that this kind of brace is very commonly needed and represents something in between an arrow and a text label. It's like an arrow in that it has to stretch while maintaining the size of its curly ends.

So I implemented a curly brace by using the Arrow command with "curly" Arrowheads. In addition, one of the four arrow heads in this construction can also be used to insert a text label. While the Graphics in Arrowheads is scaled in relation to the image size, any text appearing in it does not get rescaled. This is a feature that works to our advantage here.

braceLabel[{p1_, p2_}, lbl_, scale_: .02] := {
  Arrowheads[{
    {
     scale, 0,
     {Graphics@Circle[{1, -1}, 1, {Pi/2, Pi}], -1}
     },
    {
     scale, 1,
     {Graphics[{Circle[{-1, 1}, 1, {-Pi/2, 0}], 
        Inset[lbl, {0, 2}]}], 1}}
    }],
  Arrow[{p1, (p1 + p2)/2}],
  Arrowheads[{
    {scale, 0,
     {Graphics@Circle[{1, 1}, 1, {Pi, 3 Pi/2}], -1}},
    {scale, 1,
     {Graphics@Circle[{-1, -1}, 1, {0, Pi/2}], 1}}
    }],
  Arrow[{(p1 + p2)/2, p2}]
  }

Here is an example showing how to choose the arguments of the braceLabel:

With[{
  startPoint = {0, 0},
  endPoint = {3, 1}, 
  scale = .02
 },
 Graphics[
  braceLabel[
   {startPoint, endPoint},
   Style["label", Larger],
   scale
   ]
  ]
 ]

brace

In braceLabel, the last argument (scale) is optional.

To illustrate how the scaling of various parts (curly ends, label and stretching) are all automatically taken care of by Arrow with the various offsets I chose, here is a movie where I change some parameter periodically:

parameterChanges

It was generated with this command:

pl = Table[
   Plot[{msp[x, 2, 3, 1], mex[x, 2, 3, 1], mga[x, 2, 3, 1]}, {x, 0, 
     2.5}, PlotRange -> {{0, 2.5}, {0, 5}},
    Epilog -> {
      Red,
      braceLabel[
       {{.5, .9}, stretch {.9, 1.9}},
       Style["label", Larger],
       .02
       ],
      Blue,
      braceLabel[
       {{1, 1}, {2, 1}},
       Style["label", Larger],
       .015 stretch]
      }
    ],
   {stretch, 1, 2, .1}];

Export["m.gif", Join[pl, Most[Reverse[pl]]], 
 "AnimationRepitions" -> Infinity, "DisplayDurations" -> .07]

The label text can be styled, as shown. It can also be rotated by enclosing it, e.g., in Rotate["A", -90 Degree].

On an unrelated note - the question title could also be interpreted in a more general way. Then it should be mentioned that standard arrows and text labels can easily be added using the Drawing Tools.

Jens
  • 97,245
  • 7
  • 213
  • 499