4
$\begingroup$

I have an image that I want to place in the background of a plot and stretch it to cover the entire plot area. However, the aspect ratio of the image does not match the aspect ratio of the plot, and Inset refuses to stretch the image.

image = Image@Map[ColorData["SunsetColors"], 
   Table[(y - x^2 + 1)/2, {y, Reverse@Range[0, 1, 0.02]}, {x, 0, 1, 0.01}], {2}];
ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
 Prolog -> Inset[image, {0, 0}, {0, 0}, {1, 1}]]

enter image description here

The Inset documentation states:

  • If size is given as $\{w,h\}$, then any object $\mathit{obj}$ whose aspect ratio is not fixed will be horizontally or vertically stretched so as to fit exactly in a $w\times h$ rectangle.

  • If $\mathit{obj}$ is an object with fixed aspect ratio, then blank space will be left equally on both sides if there is a direction where the object would have to be stretched in order to fit exactly.

Evidently Inset thinks the image is an object with fixed aspect ratio. How can I get around this?

$\endgroup$

3 Answers 3

4
$\begingroup$

Combining Image and Graphics require Image to be converted to Raster which can be made by Show[image]. The second argument of Raster allows to stretch the image to the full plot range area by using Scaled coordinates:

image = Image@Map[ColorData["SunsetColors"], 
    Table[(y - x^2 + 1)/2, {y, Reverse@Range[0, 1, 0.02]}, {x, 0, 1, 0.01}], {2}];

pl1 = ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
 Prolog ->Raster[Show[image][[1, 1]], {Scaled[{0, 0}], Scaled[{1, 1}]}]]

plot1

You can also use explicit coordinates:

pl2 = ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
 Prolog -> Raster[Show[image][[1, 1]], {{0, 0}, {1, 1}}]]

plot2

Instead of Show[image][[1, 1]] one can use ImageData[image, DataReversed -> True] with the same effect.

You can also achieve the same effect by setting AspectRatio -> Full for the image inside of the Inset:

pl3 = ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
  Prolog -> Inset[Show[image, AspectRatio -> Full], 
    Scaled[{0, 0}], Scaled[{0, 0}], Scaled@1]]
pl4 = ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
  Prolog -> Inset[Show[image, AspectRatio -> Full], {0, 0}, {0, 0}, {1, 1}]]

The results are exactly identical in rendering:

Image[pl1] === Image[pl3]
Image[pl2] === Image[pl4]
True

True
$\endgroup$
2
  • $\begingroup$ Your background image is rotated. $\endgroup$
    – paw
    Commented Sep 9, 2014 at 16:35
  • $\begingroup$ @paw Thanks, fixed now. $\endgroup$ Commented Sep 9, 2014 at 16:40
2
$\begingroup$

I think that the help clearly indicates that it won't stretch it automatically. And I don't know of any sneaky way of making it do so. But you could write a helper function to stretch it for you:

Clear[insetImage];
insetImage[image_Image, pos_, opos_, size : {w_, h_}] :=
  Module[{a, b},
   {a, b} = ImageDimensions@image;
   Inset[ImageResize[image, If[w <= h, a {1, h/w}, b {w/h, 1}]], pos, opos, size]
   ];

Now just use insetImage instead of Inset and it should magically do what you want.

ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
   Prolog -> insetImage[image, {0, 0}, {0, 0}, #]] & /@ {{0.3, 0.3}, {0.3, 0.7}, {1, 0.5}, {1, 1}}

stretch

$\endgroup$
1
$\begingroup$

Is the code you posted just a working example?

You could get this plot much simpler:

DensityPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, 
 ColorFunction -> "SunsetColors", MeshFunctions -> {#3 &}, Mesh -> 9]

enter image description here

The alternative is to rescale the image manually.

image = Image@
   Map[ColorData["SunsetColors"], 
     Table[(y - x^2 + 1)/2, {y, Reverse@Range[0, 1, 0.02]}, {x, 0, 1, 
       0.01}], {2}];
image = ImageResize[image, {#1, 2*#2 - 1}] & @@ ImageDimensions@image;
ContourPlot[y - x^2, {x, 0, 1}, {y, 0, 1}, ContourShading -> None, 
   Prolog -> Inset[image, {0, 0}, {0, 0}, {1, 1}]]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Yes, it's just an example; my actual plots are more complicated. I don't want to use DensityPlot because if you export as PDF you can see ugly tessellation boundaries. ImageResize could work in a pinch, but I'm also curious if I can get Mathematica to just stretch the existing image. $\endgroup$
    – user484
    Commented Sep 9, 2014 at 1:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.