# How to scale one axis of a 3D plot?

I would like to scale one of the axes in a Parametric3DPlot. I tried adapting the recipe given in this answer to this case, but, as shown below, this attempt failed:

GraphicsRow[
Table[ParametricPlot3D[{Cos[u], Sin[u] + Cos[v], Sin[v]}, {u, 0,  2 π}, {v, -π, π},
ScalingFunctions -> {Identity, scale, Identity},
BoxRatios -> Automatic,
PlotRange -> All], {scale, {{2 # &, #/2 &},  Identity, {#/2 &, 2 # &}}}]]


Specifically, the aspect ratios are as they should be, but the numbers along the scaled y-axis are wrong. They should be the same for all three plots.

In fact, the results above are essentially the same as one would get with this:

GraphicsRow[
Table[ParametricPlot3D[{Cos[u], scale (Sin[u] + Cos[v]), Sin[v]},
{u, 0, 2 π}, {v, -π, π},
BoxRatios -> Automatic,  PlotRange -> All],
{scale, {2, 1, 1/2}}]]


...and this is decidedly not what I'm trying to do. I just want to stretch or shrink the y-axis by a specified scaling factor, but retaining all the tick marks along the axis, and keeping the numbers along the axis unchanged (only their relative spacing should change).

(Granted, there's no reason to expect ScalingFunctions to work here, since the documentation does not cover the way I'm using it.)

Is there some other way to scale the y-axis?

• Try explicitly setting the PlotRange. Oct 6, 2015 at 20:59
• Or perhaps you want AspectRatio Oct 6, 2015 at 21:01
• I think you mean BoxRatios. Oct 6, 2015 at 21:07

You can use FunctionRange to workout the ratios for BoxRatios.

funcs = {Cos[u], Sin[u] + Cos[v], Sin[v]};

range = FunctionRange[funcs, {u, v}, {x, y, z}];

br = (Cases[
range, _[_, #, _]] /. _[lower_, #, upper_] -> (upper - lower)) & /@ {x, y, z} // Flatten;

ParametricPlot3D[funcs, {u, 0,2 \[Pi]}, {v, -\[Pi], \[Pi]}, BoxRatios -> br, ImageSize -> 200]


I think this is what you're looking for:

Row@Table[
ParametricPlot3D[{Cos[u], Sin[u] + Cos[v], Sin[v]}, {u, 0,
2 \[Pi]}, {v, -\[Pi], \[Pi]}, BoxRatios -> br, ImageSize -> 200]
, {br, {{1, 4, 1}, {1, 2, 1}, {1, 1, 1}}}
]


Where BoxRatios gives the relative scaling of {x,y,z} of the bounding box. i.e. the axes.

• Thanks, but no, this is not what I am looking for. The desired solution should be invariant with respect to changes in the proportions of the underlying 3D graphics. In contrast, the solution you propose requires inspecting the proportions of the underlying base graphics, and using this information to compute the required BoxRatios to produce the desired scaling. IOW, the code above would fail to properly scale the y-axis if, for example, the function being plotted were...
– kjo
Oct 6, 2015 at 22:03
• ... parametrized with {Sin[u] + Cos[v], Cos[u], Sin[v]}, because with this new function the proportions of the underlying 3D graphics are different.
– kjo
Oct 6, 2015 at 22:03