3
$\begingroup$

I have:

f[x_] = 5 - 4/25*x^2.2;
Plot[{f[x], f[1] + (f[4] - f[1])/(4 - 1)*(x - 1), 
  f[1] + f'[1] (x - 1)}, {x, 0, 4.5},
 PlotRange -> {{0, 6}, {0, 6}},
 PlotLegends -> {"f", "secant", "tangent"},
 Epilog -> {
   Red, PointSize[Large], Point[{{1, f[1]}, {4, f[4]}}],
   Black, Line[{{1, f[1]}, {4, f[1]}, {4, f[4]}}],
   Text[Style["f", Black, Background -> White], {4.5, f[4.5]}],
   Text[Style["(x,f(x))", Black, Background -> White], {1, 
     f[1]}, {1.2, 1.2}],
   Text[Style["(x+Δx,f(x+Δx))", Black, 
     Background -> White], {4, f[4]}, {1.2, 1.2}],
   Text[Style["dx=Δx", Black, 
     Background -> White], {2.5, f[1]}, {0, -1.2}],
   },
 AxesLabel -> {"x", "y"}, AxesStyle -> Arrowheads[{0, 0.03}]
 ]

enter image description here

Now I'd like to add the distance labels dy and $\Delta x$ on the right-hand side. What's the best way to draw an arrow with arrow heads and each end and a little horizontal line above and below the arrowhead tip? I know I can do it with Graphics, but just wondering if there is already an arrowhead style that might do this.

$\endgroup$

1 Answer 1

7
$\begingroup$

We can design custom arrowheads! Define

arrow = Graphics[{
  FilledCurve[{
    Line[{
      {-1.5, 0.}, {-1.5, 0.}, {-1.95, 1.05}, {0., 0.}
      , {0., -1.05}, {0.15, -1.05}, {0.15, 1.05}, {0., 1.05}
      , {0., 0.}, {-1.95, -1.05}, {-1.5, 0.}
    }]
  }]
}]

Then, in your code, you can make two-headed arrows using

Arrowheads[{{0.015, 1, arrow}, {-0.015, 0, arrow}}]

Resizing is done by way of changing the numbers 0.015 and -0.015. If we add the above Arrowheads call and

Arrow[{{4.5, 5}, {4.5, 1.5}}]

to Epilog, the result looks like this:

enter image description here


Here's how I came up with the code for arrow (for the most part). We use the amazing arrowhead creator from this answer by Sjoerd C. de Vries and adapt it for our purposes.

First, copy and paste his first DynamicModule and add

Line[{
 top
 , {top[[1]], rightBase[[2]]}
 , {top[[1]] + 0.15, rightBase[[2]]}
 , {top[[1]] + 0.15, -rightBase[[2]]}
 , {top[[1]], -rightBase[[2]]}, top}
]

between BSplineCurve[{leftBase, outerMidLeft, top}] and BSplineCurve[{top, outerMidRight, rightBase}]. This extra bit of code will create the line at the end of the arrowhead. Then, play with the Locators for awhile until we get an arrowhead that looks nice. I chose the following:

enter image description here

As outlined in the answer linked above, we define

arrow = h /. Opacity[_] :> Sequence[];

To make things more general, you can add new Locators that define the positions of the bar at the end of the arrow in order to play around with how the arrow looks. Finally, to get the arrow as defined at the beginning of the post, I actually did

arrow = h /. BSplineCurve -> Line
  /. Opacity[_] :> Sequence[]
  /. a_?NumberQ :> Round[a, 0.15]
  //. {Line[{a__, b_}], Line[{x_, y__}], z___} :> {Line[{a, b, y}], z}

The third replacement is unnecessary, but I did it so that the code would format nicely.

$\endgroup$

Your Answer

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

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