Axes with fixed size arrows

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'? 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}]

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}] 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] Change arrow[] to arrow to get • 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. – mf67 Oct 5 '18 at 21:43
• @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} – kglr Oct 5 '18 at 21:57

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
] 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}
] 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
];

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