4
$\begingroup$

According to this post, the proper way to export 3D graphics as vector graphics is by inserting them into a 2D regular Graphics as Inset. However, I fail to get rid of a huge white frame around my original image. How can I make this tight? Here are the options that I tried:

plot3d = Graphics3D[Cylinder[], Ticks -> Automatic, Axes -> True, 
   ViewPoint -> {1.3, -2.4, 2.}, AxesLabel -> {"x", "y", "z"}];
Framed[
 Graphics[
  Inset[
   Framed[plot3d],
   Automatic, Automatic, ImageScaled[1]
   ],
  PlotRange -> {{0, 1}, {0, 1}},
  PlotRangePadding -> None,
  ImagePadding -> None,
  ImageMargins -> 0
  ]]

enter image description here

Ideally, I would also automatically choose the size of the "outer" Graphics to match the inset object such that no white margins appear and also no cropping occurs.

Update 2:

Moved previous update to a new question.

$\endgroup$
6
$\begingroup$

The problem is that the Automatic size for the Inset Graphics3D object and the Automatic size for the enclosing Graphics object are independently determined. The easiest solution is to give both of them an explicit size:

Framed @ Graphics[
    Inset[
        Framed @ Show[plot3d,ImageSize->{360,360}]
    ],
    ImageSize->{360,360}
]

enter image description here

For the example in the comments, my previous answer was not sufficient. For:

plot3d = Plot3D[100, {x, 0, 3}, {y, 0, .9},
    BoxRatios -> {3, .9, .5}, ViewPoint -> {0, -Pi, 1.3},
    ImageSize -> {700, 220}]

you can just add AspectRatio->Full:

Framed@Graphics[Inset[Framed@plot3d], ImageSize -> {700, 220}, AspectRatio->Full]

enter image description here

$\endgroup$
  • $\begingroup$ It seems to work well for this example, but why not here: plot3d = Plot3D[100, {x, 0, 3}, {y, 0, .9}, BoxRatios -> {3, .9, .5}, ViewPoint -> {0, -Pi, 1.3}, ImageSize -> {700, 220} ] and Framed@Graphics[Inset[Framed@plot3d], ImageSize -> {700, 220}] $\endgroup$ – Felix Mar 1 '17 at 3:52
5
$\begingroup$

Use:

FrameMargins -> -70

or

FrameMargins -> {{-80, -80}, {-70, -70}}

So:

plot3d = Graphics3D[Cylinder[], Ticks -> Automatic, Axes -> True, 
   AxesLabel -> {"x", "y", "z"}];
Framed[Graphics[
  Inset[Framed[plot3d], Automatic, Automatic, ImageScaled[1]], 
  PlotRange -> {{0, 1}, {0, 1}}, PlotRangePadding -> None, 
  ImagePadding -> None, ImageMargins -> 0], 
  FrameMargins -> {{-80, -80}, {-70, -70}}]

A humble recommendation to the question poser (and others): Please use the minimal case for asking a question. You didn't need to include axes, label axes, include ticks, use image padding, scale the image, set the plot range, and such. Look how much simpler your code could have been:

Framed[
 Graphics[
  Inset[
   Framed[
    Graphics3D[
     Cylinder[]]]]]]

or

Framed[Graphics[Inset[Framed[Graphics3D[Cylinder[]]]]]]
$\endgroup$
  • $\begingroup$ Thank you David, I will try to do better next time. Is there a way to make your solution work without the frames? I actually used them only to show that there is a lot of wasted space. But then, FrameMargins is an option of Framed. $\endgroup$ – Felix Mar 1 '17 at 3:59
  • $\begingroup$ You can use FrameStyle->None to hide the Frame. $\endgroup$ – Carl Woll Mar 1 '17 at 6:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.