7
$\begingroup$

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?

$\endgroup$
5
  • 1
    $\begingroup$ I don't know, but would you consider an alternative way of highlighting a region, say Show[your stuff, Graphics[{Pink, Opacity[0.5], Rectangle[{0, 0}, {1, 2}]}]] ? $\endgroup$ Jan 18, 2013 at 15:27
  • 3
    $\begingroup$ Related question: Scale Insetted Characters to Plot $\endgroup$
    – Jens
    Jan 18, 2013 at 15:28
  • $\begingroup$ The linked question only answers my question for vertical braces, but I would also like to draw them horizontally to mark areas on the x-axis. @b.gatessucks Thanks for that, but I already have an alternative. However, I would like to use the braces instead. $\endgroup$
    – 2dpc
    Jan 18, 2013 at 16:11
  • $\begingroup$ @spinut Did you look at the angle argument in this answer? $\endgroup$
    – ssch
    Jan 18, 2013 at 16:21
  • $\begingroup$ @ssch This answer actually provided the best solution for me: mathematica.stackexchange.com/a/4377/5321 Thanks for your help $\endgroup$
    – 2dpc
    Jan 18, 2013 at 16:35

1 Answer 1

16
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ This is a great solution and exactly what I was looking for. Thank you! $\endgroup$
    – 2dpc
    Jan 19, 2013 at 23:49
  • $\begingroup$ Congrats on the 20k! :) $\endgroup$
    – rm -rf
    Jan 20, 2013 at 7:38
  • $\begingroup$ @rm-rf Thanks - and spinut, I'm glad it helped. $\endgroup$
    – Jens
    Jan 20, 2013 at 8:02

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.