# Composing an image with a plot

I'm trying to illustrate the solutions to a textbook problem dealing with quadratic functions.

This will involve plotting a quadratic and overlaying the plot and the image.

Here is the textbook scan..... The idea of the problem is to find several possible quadratic models that would go through the hoop.

I imported this image into a variable, call it img1

I wanted to establish a "baseline" so I started with a simple plot, x intercepts of 0 and 18, and vertex at (9,14). I know, NOT a solution to the problem but I wanted to see how the plot and image would match up.

I created the plot

g2 = Plot[-14/81 x (x - 18), {x, -1, 19}, PlotStyle -> Thick]


Then I put them together and tweaked the placement of the plot based on the image size.

ImageCompose[img1, g2, {983/2, 811/2}]


Which gives me this... The vertex is in the right place, but the axes don't line up.

Sorry if this is a dumb question, I'm not at all sure how I could get my plot to match the background image so the axes in the image would be the same as the axes in my plot....

Do I need to scale my plot, or scale my image.. or something obvious that I am missing.

Any help is appreciated

• If you right click a graphic or an image, there's a tool to "get coordinates". You can click on a number of points, then use Control-C to copy the coordinates. This can be helpful for aligning the image coordinate system with Plot's coordinate system. Alternatively, instead of using an image with a grid on it, could use only an image of a boy with a basketball, and place that image on the plot using the Epilog option. You could also place a basket :-) Apr 9, 2013 at 15:11
• @Szabolcs I just read your comment after I did exactly that for my answer. :) Apr 9, 2013 at 15:26
• The answers with Manipulate reminded me of this question: Animate ParametricPlot3D for two different parametric equations
– Jens
Apr 9, 2013 at 18:38

Try this:

(* clip white borders *)
img = ImageCrop[Import["http://i.stack.imgur.com/La8Zs.jpg"]];

Plot[-14/81 x (x - 18), {x, -2, 19},
PlotRange -> {-2, 16}, PlotStyle -> Directive[Red, Thick, Dashed],
Prolog -> {Texture[img],
Polygon[{Scaled[{0, 0}], Scaled[{1, 0}], Scaled[{1, 1}], Scaled[{0, 1}]},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]},
Ticks -> None] Notes:

• If you want to fit in an image as background, you will often want to trim margins; ImageCrop[] is a good function for the purpose.

• Luckily, your background image has its own coordinate system; you can then adjust PlotRange appropriately.

• Prolog is most useful for putting primitives in the background.

• Scaled[] ensures that the background textured polygon is scaled appropriately with respect to the plot range.

• Thanks so much, that helps a TON. I'll be using this question in just a few hours, so I can get it to work NOW, and think about some of the ideas you mentioned. I really appreciate the help! Apr 9, 2013 at 15:01
• Such a superior answer. It. Hurts. Me. :)
– BoLe
Apr 9, 2013 at 17:53
• I know we shouldn't write comments like "Thanks!" and so on, but thanks. That has just saved me probably a week of work and workarounds. May 13, 2013 at 15:24
• @yohbs, you're welcome! I'm glad my attempt saved you some effort. :) May 13, 2013 at 15:25

EDIT: (see below for old version)

New version with alpha channels, the option to lock the graph at the ball, adjustable player position and a button to remove player and basket:

setalpha[im_] :=
ChanVeseBinarize[im, TargetColor -> {1., 1., 1.},
"LengthPenalty" -> 10]},

guy = setalpha[

Manipulate[
Plot[If[locked, (-c - b pos[] + pos[])/pos[]^2, a] x^2 +
b x + c, {x, 0, 16}, PlotRange -> {{0, 17}, {0, 14}},
Frame -> True,
ImageSize -> 500,
BaseStyle -> {20, FontFamily -> "Helvetica"},
FrameLabel -> {"Distance from Back of hoop (ft)", "Heigth (ft)"},
GridLines -> {Range@16, Range@14},
Prolog -> {Inset[If[show, basket, ""], {0.5, 8}, Top, 1],
Inset[If[show, guy, ""], pos, Top, 2.5]}],
Item@Row[{"a  ",
Dynamic@Slider[Dynamic@a, {1, 10}, Enabled -> ! locked]}],
Item@Row[{"b  ", Dynamic@Slider[Dynamic@b, {1, 10}]}],
Item@Row[{"c  ", Dynamic@Slider[Dynamic@c, {1, 10}]}],
{{pos, {16, 6}}, Locator},
{{locked, True, "Lock graph at ball"}, {True, False}},
{{show, True, "Show player and basket"}, {True, False}},
ControlPlacement -> Left] Old version:

Alternatively, you can also create the whole thing completely in Mathematica. I also added Manipulate for fun:

basket = Import[

Manipulate[
Plot[-(c x - b)^2 + a, {x, 0, 16},
PlotRange -> {{0, 17}, {0, 14}},
Frame -> True,
ImageSize -> 500,
BaseStyle -> {20, FontFamily -> "Helvetica"},
FrameLabel -> {"Distance from Back of hoop (ft)", "Heigth (ft)"},
GridLines -> {Range@16, Range@14},
Prolog -> {Inset[basket, {0.5, 8}, Top, 1],
Inset[guy, {16, 6}, Top, 2.5]}],
{a, 8, 20}, {b, 1, 10}, {c, 0.1, 1}]

• Wow! Looks fantastic, I'll check that out later today when I have time. This is nice since I could have buttons to show the "guy" and "hoop", take them off once the student gets into the problem. Really nice. I really appreciate seeing solutions like this since I can really connect to the commands being used since they apply directly to my problem. Thanks for your time! Apr 9, 2013 at 15:47
• Now the player only needs a tad alpha channel to remove the white background Apr 9, 2013 at 16:01
• @YvesKlett the new version comes with alpha channels. Thanks for the link, btw. It's really useful! :) Apr 9, 2013 at 18:01

I enlarge the image canvas if throw flies outside.

together[i, {4, 22, 10}] Parabola with zeroes x1, x2 and vertex at {(x1 + x2)/2, y3}:

y[{x1_, x2_, y3_}, x_] := -4 (x - x1) (x - x2) y3/(x1 - x2)^2

i = ImageCrop@Import@"http://i.stack.imgur.com/La8Zs.jpg";


Note ImageCrop, it ensured me constant ImageDimensions[i]/{21, 18} pixels for each unit.

together[i_Image, {x1_, x2_, y3_}] :=
Module[{p, r, u, v},
{u, v} = ImageDimensions@i/{21., 18.};
p = Plot[y[{x1, x2, y3}, x], {x, x1, x2},
PlotRange -> {{x1, x2}, {0, y3}},
AspectRatio -> Automatic,
PlotStyle -> Directive[Red, AbsoluteThickness]];
r = PlotRange /. AbsoluteOptions[p, PlotRange];
p = Image[p, ImageSize -> u Abs[Subtract @@ First[r]]];
p = SetAlphaChannel[p, Dilation[ColorNegate@Binarize@p, 1]];
With[{pl = Max[0, -1 - x1]}, 