2
$\begingroup$

I'm trying to get a constant/uniform size on the arrow heads for the “$x$” and “$y$” axis in 2D plots for all my plots but they seem to change depending on the aspect ratio. I have managed to get the tick mark and label fonts constant/uniform, but have not found a solution to the arrow heads “problem”. Is there a solution to this?

There seem to be “solutions” to the problem for individual arrows using Line and polygons but none(?) for the automatic arrows on the plot axis?

I tried constructing an arrow head using polygons but it cannot be placed over the axis (only half of the arrow head is visible)

Are there any function/commands that I can use to place a graphical object in a plot, even outside the plotting 'border'?

The arrow is cut by plotting border

a = -15;
location = {π + 0.5, 0};
arrow =
  Polygon[{
    location,
    Offset[{a, 5}, location],
    Offset[{0.7 a, 0}, location],
    Offset[{a, -5}, location]
  }];
arr = Graphics[arrow];
Plot[Sin[x], {x, 0, π}, 
  PlotRange -> {{0, π + 0.5}, {0, 1.5}},
  ImageSize -> Medium, 
  Epilog -> {arrow}]
$\endgroup$
0

2 Answers 2

3
$\begingroup$
ClearAll[arrow]
arrow[ sc_: 1, a_: {15, 5}] := Graphics[Polygon[{{0, 0}, Offset[sc {-1, 1} a, {0, 0}], 
          Offset[sc {-7/10, 0} a, {0, 0}], Offset[-sc a, {0, 0}]}]];

Examples:

Plot[Sin[x], {x, 0, π}, PlotRange -> {{0, π}, {0, 1.5}}, 
  PlotRangePadding -> {{Automatic, Scaled[.1]}, Automatic}, 
  ImageSize -> 500, 
  AxesStyle -> {Arrowheads[{{1/100, 1, arrow[]}}], Automatic}]

enter image description here

 Grid @ Partition[Plot[1 + Sin[x], {x, 0, 2 Pi}, 
     AxesStyle -> Arrowheads[{{0.3, 1, arrow[]}}], 
     ImageSize -> #, AspectRatio -> #2] & @@@ Tuples[{{200, 400}, {1/2, 1}}], 2] 

enter image description here

Change arrow[] to arrow[2] to get

enter image description here

$\endgroup$
2
  • $\begingroup$ This is very nice. Far above my skills. I've notices as I make the axes lines thicker the fine tip of the arrow gets "over printed" by the axes line. Is there some way to either retract the axis line "back" into the thicker part of the arrow head or underlay the narrowing part of the arrowhead with a white square/rectangle or a white wider version of the arrow head. That would cut out any line interfering with the arrow tip. $\endgroup$
    – mf67
    Commented Oct 5, 2018 at 21:43
  • 1
    $\begingroup$ @mf67, you can the form {s, pos, {arrow[], setback}} to get the shaft foreshortened by setback, e.g., AxesStyle -> {Directive[Thickness[.005], Arrowheads[{{1/100, 1, {arrow[], 1}}}]], Automatic} $\endgroup$
    – kglr
    Commented Oct 5, 2018 at 21:57
1
$\begingroup$

As far as your specific question about why only half the arrow is show, this is due to the option PlotRangeClipping->True. Setting this option to False gives:

Plot[Sin[x], {x, 0, π}, 
    PlotRange -> {{0, π + 0.5}, {0, 1.5}},
    ImageSize -> Medium,
    Epilog -> {arrow},
    PlotRangeClipping -> False
]

enter image description here

On the other hand, I think the canonical approach to this issue is to use AxesStyle with an Arrowheads directive, as in @kglr's answer. Unfortunately, the natural approach doesn't work, and I would suggest reporting this to support:

Plot[Sin[x], {x, 0, π},
    PlotRange -> {{0, π + 0.5}, {0, 1.5}},
    ImageSize -> Medium,
    AxesStyle -> {Arrowheads[Medium], Automatic}
]

enter image description here

For some reason, Mathematica gets confused about how much image padding is needed. One workaround is to use my function GraphicsInformation to figure out the default image padding, and then to explicitly set this:

<<GraphicsInformation`

plot = Plot[Sin[x], {x, 0, Pi},
    PlotRange -> {{0, π + 0.5}, {0, 1.5}},
    ImageSize -> Medium
];
pad = "ImagePadding" /. GraphicsInformation[plot]

Plot[Sin[x], {x, 0, π},
    PlotRange -> {{0, π + 0.5}, {0, 1.5}},
    ImageSize -> Medium,
    AxesStyle -> Arrowheads[Medium],
    ImagePadding ->pad
]

{{17., 1.5}, {17., 0.5}}

enter image description here

Another workaround is to create an explicit arrow graphic using Offset, and then to use that graphic inside of the Arrowheads directive as in @kglr's answer.

$\endgroup$
1
  • $\begingroup$ Perhaps someone much more skilled than I could report it to support? I would not be able to phrase it as they would understand it. It would be good with some inbuilt function to support more "fixed" sizes and shapes for the axes arrows. $\endgroup$
    – mf67
    Commented Oct 5, 2018 at 21:48

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.