# How to make 3 dimensional arrows look good when their lengths are wildly different?

I was trying to adapt Jens's answer for adding arrows to a 3D graphics into a general plotting function here. But I find that when I try to combine the Graphics3D object with the Plot3D it makes the arrows ugly when the x, y, and z axes have different length scales. Essentially, the Plot3D will always have a BoxRatio near to {1 ± 0.5, 1 ± 0.5, 1 ± 0.5}

lengths1 = {2, 2, .1};
lengths2 = {2, 2, 2};
lengths3 = {2, 2, 100};
arrowfunc[
lengths_] := {RGBColor @@ #, Arrow[Tube[{{0, 0, 0}, #}]]} & /@
DiagonalMatrix[lengths];
Graphics3D[arrowfunc@#, BoxRatios -> {1, 1, 1}] & /@ {lengths1,
lengths2, lengths3}


Is there any way to modify arrowfunc to make these all look basically identical? I've tried adding Arrowheads with a Scaled size, but it didn't work; likewise adding a Scaled radius to the Tube function.

What follows is unfortunately not a completely satisfactory answer; I decided to share it because some parts of it seem to work despite my best efforts to understand why...

I am using Mathematica 10.3.0.0 on Win7-64bit. These are Jason's definitions:

lengths1 = {2, 2, .1};
lengths2 = {2, 2, 2};
lengths3 = {2, 2, 100};


If 2D arrows are acceptable rather than tube-based ones, then apparently setting the size by using the symbolic values Small, Medium, Large etc seems to work much better:

Function[{lengths},
Graphics3D[{
(* notice symbolic size indicator *)
Arrow[{{0, 0, 0}, #}] & /@ DiagonalMatrix[lengths]
},
BoxRatios -> {1, 1, 1}, Axes -> True, ImageSize -> 300,
TicksStyle -> {Black, Black, Directive[Medium, Red]},
(* ViewAngle is the puzzling part: why do I need this? *)
ViewAngle -> 35 Degree
]
] /@ {lengths1, lengths2, lengths3}


This does not work with 3D tube-based arrows though.

The puzzling observation is in the fact that, using the exact same function but leaving out the ViewAngle directive, or alternatively setting it to Automatic or All, I first obtain the following graphics:

If I then simply click on each of them, or rotate them, or in any other way interact with them, then I obtain the same thing as the graphic shown above that had an explicit setting of ViewAngle:

I find this behavior quite bizarre, and can offer no better explanation for it than a front-end glitch.

• Thank you, this does satisfy the need for the arrows to be independent of their size, but when I try to combine them with a 3D plot, as in this code, it becomes hard to see them. Commented Dec 9, 2015 at 14:50
• @JasonB Perhaps try changing the color of the arrows to one that stands out better against your plot (e.g. Blue), and including the ViewAngle directive in the last Show, rather than in the arrowaxisfunc, i.e. Show[plot, arrows,ViewAngle -> 35 Degree] within your threeDArrowPlot2. Not perfect by any means, but maybe slightly better. Try also adding Appearance -> "Projected" within the Arrowheads[] directive, i.e. Arrowheads[Large, Appearance -> "Projected"]. Commented Dec 9, 2015 at 16:04