2
$\begingroup$

I have a Graphics object for a detailed plot that has too many points and regions in it to be quickly rendered, which I want to use as a background for a Manipulate. How can I pre-render the plot into an image, without losing the coordinates of the parts of the Graphics?

g = Graphics[Disk[]];
Show[g, Graphics[{Red, Thickness[.01], Circle[]}]]
Show[Image[g], Graphics[{Red, Thickness[.01], Circle[]}]]
Show[Rasterize[g], Graphics[{Red, Thickness[.01], Circle[]}]]

Here the first graphic displays correctly (the red border lines up with the disk) but the latter two, which prerender the disk, also put it at the rectangle {{0, 400}, {0, 400}} or something, rather than being centered at 0 with radius 1, like it was originally. (You can see a tiny red border in the bottom left of the latter two.)

Edit: Here is another example which some of the given solutions don't replicate. Here the bounding boxes of the two graphics don't match up. In this example the black disk should be under the right circle, not both of them or the middle.

g = Graphics[Disk[{1, 0}]];
Show[g, Graphics[{Red, Thickness[.01], Circle[], Circle[{1, 0}]}]]
$\endgroup$
3
$\begingroup$

If you use the same settings for PlotRange and PlotRangePadding when producing the Graphics objects you can align the Rasterized graphics with others easily:

g = Graphics[Disk[{1, 0}], PlotRange -> {{-1, 2}, {-1, 1}}, 
   PlotRangePadding -> Scaled[.01]];
Show[g, Graphics[{Green, Thickness[.01], Circle[], Circle[{1, 0}]}, 
  PlotRange -> {{-1, 2}, {-1, 1}}, PlotRangePadding -> Scaled[.01]]]

enter image description here

A few variations using Show + Inset and Overlay:

Graphics[{Inset[Rasterize[g], Automatic, Automatic, Scaled[1]], Red, 
  Thickness[.01], Circle[], Circle[{1, 0}]}, 
 PlotRange -> {{-1, 2}, {-1, 1}}, PlotRangePadding -> Scaled[.01]]
Show[Graphics@Inset[Rasterize[g], Automatic, Automatic, Scaled[1]], 
 Graphics[{Red, Thickness[.01], Circle[], Circle[{1, 0}]}], 
 PlotRange -> {{-1, 2}, {-1, 1}}, PlotRangePadding -> Scaled[.01]]
Show[Graphics[{Red, Thickness[.01], Circle[], Circle[{1, 0}]}], 
 Prolog -> Inset[Rasterize[g], Automatic, Automatic, Scaled[1]], 
 PlotRange -> {{-1, 2}, {-1, 1}}, PlotRangePadding -> Scaled[.01]]
Graphics[{Red, Thickness[.01], Circle[], Circle[{1, 0}]}, 
 Prolog -> Inset[Rasterize[g], Automatic, Automatic, Scaled[1]], 
 PlotRange -> {{-1, 2}, {-1, 1}}, PlotRangePadding -> Scaled[.01]]
Overlay[{Rasterize[g], 
  Graphics[{Red, Thickness[.01], Circle[], Circle[{1, 0}]}, 
   PlotRange -> {{-1, 2}, {-1, 1}}, PlotRangePadding -> Scaled[.01]]}]

all give

enter image description here

$\endgroup$
  • $\begingroup$ It looks like the example was a bit too spartan; with the updated example none of these solutions appear to work. $\endgroup$ – Mario Carneiro Aug 12 '18 at 10:27
  • $\begingroup$ @MarioCarneiro, please see the updated version. $\endgroup$ – kglr Aug 12 '18 at 10:49
1
$\begingroup$

You can do this with Inset. Take care to set ImageSize for both the rasterized object and the graphic, as this is necessary to make the coordinate systems match.

g = Graphics[Disk[]];
Graphics[{
  Inset[Rasterize[g, ImageSize -> 300]],
  Red, Thickness[.01], Circle[]
  }, ImageSize -> 300]

Mathematica graphics

This is the code for your second example:

g = Graphics[Disk[{1, 0}]];
Graphics[{
  Inset[Rasterize[g, ImageSize -> 200], {1, 0}],
  Red, Thickness[.01], Circle[], Circle[{1, 0}]
  }, ImageSize -> 300]

Mathematica graphics

The disk should be centered at {1, 0} – for this we use the second argument of Inset. For the size, you need to think of the enclosing graphic as a canvas. If you set ImageSize to 300 then this means that the width of the canvas will be 300. The background disk is 2/3 of the width of the full graphic, so in order for the coordinate systems to match we should set its ImageSize to 2/3 of the ImageSize of the enclosing graphic, i.e. 200.

You can also set the size of the object with scaled coordinates, which kglr showed in a now deleted answer. You can look into the fourth argument of Inset for this.

$\endgroup$
  • $\begingroup$ What should I do when the current view of the Show does not match the original graphic's bounding box, as in the new example? $\endgroup$ – Mario Carneiro Aug 12 '18 at 10:28
  • $\begingroup$ @MarioCarneiro I updated the answer. $\endgroup$ – C. E. Aug 12 '18 at 10:40
  • $\begingroup$ How can I determine the center of the bounding box for passing to Inset? Ideally I'd like to have a function that just depends on g. $\endgroup$ – Mario Carneiro Aug 12 '18 at 10:42
  • $\begingroup$ @MarioCarneiro Like I said, the center comes from the graphics. In this case, it's easy because the center of the disk is the center graphic. Sometimes the center is not easy to position, in that case you can use the third argument of Inset to specify another point that you know how to position in the enclosing graphic. $\endgroup$ – C. E. Aug 12 '18 at 11:02

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.