# Controlling Graphics3D aspect ratio when ViewMatrix is explicitly defined

My goal here is to visualize 3D data using an oblique cabinet projection. I would like to be able to adjust the "depth" or spacing of the Z-axis, maintain a golden ratio between the X and Y axes, and avoid cropping any data out of the figure.

So far I've found that I can use Graphics3D's ViewMatrix option to rescale the data to a unit cube, then project that cube as desired. This approach gives me the desired projection, but pushes most of my z-axis out of the PlotRange, cropping the data. PlotRange doesn't seem to adjust the plot to include the projected values.

I can apply a rescaling transform to the cube to warp the Z-axis depth, but then I get a gap between the top of the figure (where the title is) and the plot. This seems to be because the Graphics3D object is forced to remain square shaped, which doesn't apply when the ViewMatrix option goes unspecified.

Is there some way to include all the data within the figure and maintain the desired aspect ratio? The data shown are just a toy example, so I'd like this to be a generalizable approach if possible. I've been struggling with this for a while so any tips would be greatly appreciated. Thank you!!

Code for synthetic example:

data = Quiet@
Table[Table[{z, x,
Exp[-((x - 3 - z)/(.2*(1 + z/4)))^2] + .75 (1 +
z/10) Exp[-((x - 1 - z/2)/(.5 (1 - z/15)))^2]}, {x, 0, 10,
0.02}], {z, 0, 8, 1}];

(* rescale to unit cube and warp it *)
zDepth = 0.1;
rescaleToUnitCube = RescalingTransform[{{0, 8}, {0, 10}, {0, 1.35}}];
scaleDepth = ScalingTransform[{zDepth, 1, 1/GoldenRatio}];
transformationMatrix =
TransformationMatrix@Composition[scaleDepth, rescaleToUnitCube];

(* oblique projection  *)
projectionMatrix = {{1/Sqrt[2], 1, 0, 0}, {1/Sqrt[2], 0, 1, 0}, {1, 0,
0, 0}, {0, 0, 0, 1}};

(* plotting results *)
ListPointPlot3D[
data,
PlotLabel -> "Example Title",
ViewMatrix -> {transformationMatrix, projectionMatrix},
PlotRange -> {All, All, All}]


Use the option PlotRegion to specify "what region of the final display area a plot should fill" and add the plot label using the function Labeled:

Labeled[ListPointPlot3D[data,
ViewMatrix -> {transformationMatrix, projectionMatrix},
PlotRange -> {All, All, All},
PlotRegion -> {{.1, .9}, {.1, 1.3}}],
Style["Example Title", "GraphicsLabel"], Top]


• This is helpful - thank you. Is there no way to achieve the same while maintaining the Graphics3D head? Nov 9 '20 at 21:21
• @sbernasek, you can use Show[ListPointPlot3D[data, ViewMatrix -> {transformationMatrix, projectionMatrix}, PlotRange -> {All, All, All}, PlotRegion -> {{.1, .9}, {.1, 1.2}}], Graphics3D[Text[Style["Example Title", "GraphicsLabel"], Scaled@{.5, .5, 1.15}]]]?
– kglr
Nov 9 '20 at 21:30
• Perfect - thanks again. Nov 9 '20 at 21:54