How to avoid the wiggly text on Ticks and Labels when rotating 3D objects
Not a complete answer, but I think this can get you close to the solution.
If you use images instead of text, there's less (or even no) jumping around. I only worked on the ticks.
To have the ticks numbers rasterized, I made a variation of this, but there's probably a simpler way (I didn't try to put your ticks specification, but it should be easy).
Then, I played with the sizes and resolutions, and my end result still needs a lot of tuning: line thickness / darkness are a little lost in rasterings and resizings, numbers are flickering (but I do believe that they are not jumping; you tell me...)
I hope this helps as a start:
tickF[div1_, div2_: - 1] := (If[div2 == -1,
Thread[{#, #, {.02, 0}}, List, 2] &@FindDivisions[{#1, #2}, div1],
Join @@
MapAt[Join @@ # &, {Function[{p}, {p,
Magnify[Rasterize[p, RasterSize -> 150], 3], {.02,
0}}] /@ #[[1]],
Thread[{#, "", {.01, 0}}, List, 2] & /@ #[[2]]} &@
FindDivisions[{#1, #2}, {div1, div2}], {2}]]) &
examplePlot[j_] :=
ParametricPlot3D[
Evaluate@Table[{k, s, Sin[k s] + k s/50}, {k, 7}], {s, 0, 4 Pi},
PlotRange -> {{-2, 4 Pi}, {0, 4 Pi}, {-2, 4}},
BoxRatios -> {1, 3, 1}, PlotStyle -> Array[Hue, 7, {0, 0.75}],
PlotPoints -> 150, MaxRecursion -> 5,
BaseStyle -> {FontSize -> 14, FontFamily -> "Helvetica",
FontTracking -> "Plain",
TextJustification -> 0,
PrivateFontOptions -> {"OperatorSubstitution" -> False}},
ImageSize -> {3*700, 3*300},
Ticks ->
Evaluate@({(t1 = {##}; tickF[8, 5][##]) &, (t2 = {##};
tickF[8, 5][##]) &, (t3 = {##}; N /@ tickF[8, 5][##]) &}),
ViewPoint -> {3, 0.4 + 0.5 Sin[j], 0.5 + 0.2 Cos[j]},
RotationAction -> "Clip",
ViewVertical -> {0, 0, 1},
ViewAngle -> 0.22,
AxesEdge -> {{1, -1}, Automatic, {1, -1}},
AxesLabel -> {"Axis 1", "Axis 2", "Axis 3"}];
animExample =
Table[ImageResize[Rasterize[examplePlot[j], "Image"], 700], {j, 0, 2 \[Pi], \[Pi]/25}];
EDIT
Still based on rasterization, but better looking:
tickF[div1_,
div2_: - 1] := (If[div2 == -1,
Thread[{#, #, {.02, 0}}, List, 2] &@FindDivisions[{#1, #2}, div1],
Join @@
MapAt[Join @@ # &, {Function[{p}, {p, p, {.02, 0}}] /@ #[[1]],
Thread[{#, "", {.01, 0}}, List, 2] & /@ #[[2]]} &@
FindDivisions[{#1, #2}, {div1, div2}], {2}]]) &
examplePlot[j_, factor_] :=
ImageResize[
Rasterize[
ParametricPlot3D[
Evaluate@Table[{k, s, Sin[k s] + k s/50}, {k, 7}], {s, 0, 4 Pi},
PlotRange -> {{-2, 4 Pi}, {0, 4 Pi}, {-2, 4}},
BoxRatios -> {1, 3, 1},
PlotStyle -> Array[{Hue[#], Thickness[0.006]} &, 7, {0, 0.75}],
PlotPoints -> 150, MaxRecursion -> 5,
BaseStyle -> {FontSize -> factor*14, FontFamily -> "Helvetica",
FontTracking -> "Plain",
TextJustification -> 0,
PrivateFontOptions -> {"OperatorSubstitution" -> False}},
ImageSize -> {factor*700, factor*300},
ViewPoint -> {3, 0.4 + 0.5 Sin[j], 0.5 + 0.2 Cos[j]},
RotationAction -> "Clip",
ViewVertical -> {0, 0, 1},
ViewAngle -> 0.22,
AxesEdge -> {{1, -1}, Automatic, {1, -1}},
AxesLabel -> {"Axis 1", "Axis 2", "Axis 3"},
Ticks ->
Evaluate@({(t1 = {##}; tickF[8, 5][##]) &, (t2 = {##};
tickF[8, 5][##]) &, (t3 = {##}; N /@ tickF[8, 5][##]) &}),
BoxStyle -> Directive[Thickness[0.003]]
], "Image", RasterSize -> 4000], 700, Resampling -> "Linear"]
animExample6 = Table[examplePlot[j, 6], {j, 0, 2 \[Pi], \[Pi]/25}];
Export["animExample.GIF", animExample6,
"DisplayDurations" -> 0.15, "AnimationRepetitions" -> Infinity]
(not sure if factor
is doing that much... but at least it is better looking, simpler and faster)
It seems that the reason for the text wiggling is that on rendering the textual elements are aligned to the pixel grid. To avoid wiggling we should avoid using of font glyphs. P. Fonseca has showed the rasterization approach. I will show the outlining approach using the core of his tickF
function:
baseStyle = {FontSize -> 18, FontFamily -> "Helvetica", FontTracking -> "Plain",
TextJustification -> 0, PrivateFontOptions -> {"OperatorSubstitution" -> False}};
outl = First@ImportString[ExportString[Style[#, baseStyle], "PDF"], "PDF"] &;
lbls = outl /@ {"Axis 1", "Axis 2", "Axis 3"};
tickF[div1_, div2_: - 1] :=
If[div2 == -1, Thread[{#, #, {.02, 0}}, List, 2] &@FindDivisions[{#1, #2}, div1],
Join @@ MapAt[
Join @@ # &, {Function[{p}, {p, outl[p], {.02, 0}}] /@ #[[1]],
Thread[{#, "", {.01, 0}}, List, 2] & /@ #[[2]]} &@
FindDivisions[{#1, #2}, {div1, div2}], {2}]] &;
examplePlot =
ParametricPlot3D[Evaluate@Table[{k, s, Sin[k s] + k s/50}, {k, 7}], {s, 0, 4 Pi},
PlotRange -> {{-2, 4 Pi}, {0, 4 Pi}, {-2, 4}}, BoxRatios -> {1, 3, 1},
PlotStyle -> Array[Hue, 7, {0, 0.75}], PlotPoints -> 150, MaxRecursion -> 5,
ImageSize -> {700, 300}, ViewAngle -> 0.19,
Ticks -> {tickF[8, 5], tickF[8, 5], tickF[8, 5]}];
animExample =
Table[Show[examplePlot, ViewPoint -> {3, 0.4 + 0.5 Sin[j], 0.5 + 0.2 Cos[j]},
RotationAction -> "Clip", ViewVertical -> {0, 0, 1}, ViewAngle -> 0.22,
AxesEdge -> {{1, -1}, Automatic, {1, -1}}, AxesLabel -> lbls], {j, 0,
2 \[Pi], \[Pi]/25}];
Export["animExample.GIF", animExample, "DisplayDurations" -> 0.15,
"AnimationRepetitions" -> Infinity]