9
$\begingroup$

I am trying to plot a contour of a function g[x,y] (in particular, the contour g[x,y]==1 on a different set of axes than (x,y): I want to plot it on (f1[x], f2[y]), where f1 and f2 are (monotone increasing) functions of a single variable, g[x,y] is monotone increasing in x and monotone decreasing in y, and all 3 functions are complicated enough that I cannot invert them (analytically, and probably not numerically either). I managed to plot g=1 vs. (x,y) but can't figure out how to plot it against (f1[x], f2[y]) without setting up huge tables of data and then just plotting points. I can only conceive of it along the lines of

ParametricContourPlot[g[x, y] == 1, {f1[x], f2[y]}, {x, 0, 10}, {y, 0, 10}]

but of course that doesn't exist (AFAIK). Any ideas?

EDIT: My thanks to Bill and Rahul for their quick answers, and my apologies for any ambiguity in my original post. Rahul correctly interpreted what I needed--my sincere (and awed) thanks! My f1, f2 and g functions are so complicated I can't even write them in closed form, but Rahul's suggestion worked perfectly. (I still don't understand how MeshFunctions works to map the function onto the new axes, but it clearly does.)

$\endgroup$
11
$\begingroup$

Let's call $u=f_1(x)$ and $v=f_2(y)$. Do you want to plot $g(u,v)=1$ against $x$ and $y$, or $g(x,y)=1$ against $u$ and $v$? @bill's answer does the former. Here's a way to do the latter: Use ParametricPlot, and define the contour using MeshFunctions.

f1[x_] := Log[1 + x]
f2[y_] := Exp[y] - 1
g[x_, y_] := x^2 + y^2

ParametricPlot[{f1[x], f2[y]}, {x, -1.2, 1.2}, {y, -1.2, 1.2}, 
 MeshFunctions -> {Function[{u, v, x, y}, g[x, y]]}, Mesh -> {{1}}, 
 MeshStyle -> Directive[Opacity[1], Black]]

enter image description here

You can set PlotStyle -> None, BoundaryStyle -> None, Axes -> False if you want it to look more similar to the default ContourPlot.

Unfortunately, it seems that MaxRecursion doesn't help to improve the contour, so if you need better quality you'll have to increase PlotPoints.

$\endgroup$
8
$\begingroup$

It's simpler than you fear. First the command is ContourPlot... for a simple g, this will give you the circle of radius 1.

g[x_, y_] := x^2 + y^2;
ContourPlot[g[x, y] == 1, {x, -2, 2}, {y, -2, 2}]

Now say you have the two functions f1 and f2

f1[x_] := Log[x];
f2[y_] := Exp[y];
ContourPlot[g[f1[x], f2[y]] == 1, {x, -2, 2}, {y, -2, 2}]

Mathematica graphics

Now you get the contour plot of the nested functions.

$\endgroup$
3
$\begingroup$

You can also post-process the output of ContourPlot to transform the contour lines using a transformation that depends on two functions t1 and t1:

postProcess[t1_, t2_, col_: LightBlue] := Show[# /. GraphicsComplex[c_, p_] :> 
   GraphicsComplex[Transpose[{t1 /@ #, t2 /@ #2} & @@ Transpose[c]], p], 
    PlotRange -> All] /. Line[x_] :> {Thick, Line[x], col, Polygon[x]} &

Using the example in @Rahul's answer with a slight modification:

f1[x_] := Re @ Log[1 + x]
f2[y_] := Re[Exp[y] - 1]
g[x_, y_] := x^2 + y^2

cp = ContourPlot[g[x, y] == 1, {x, -1.2, 1.2}, {y, -1.2, 1.2}, 
   FrameLabel -> {{Style["y", 16], ""}, {Style["x", 16], ""}},  ImageSize -> 400];

Row[{cp, Show[postProcess[f1, f2] @ cp,  FrameLabel -> 
  {{Style[Subscript[f, 2][y], 16], ""}, {Style[Subscript[f, 1][x], 16], ""}}]}, 
 Spacer[10]]

enter image description here

cp2 = ContourPlot[g[x, y], {x, -1.2, 1.2}, {y, -1.2, 1.2}, 
  Contours -> {.1, .5, 1}, FrameLabel -> {{Style["y", 16], ""}, {Style["x", 16], ""}}, 
  ImageSize -> 400, ContourShading -> None];

Row[{cp2, Show[postProcess[f1, f2] @ cp2,  FrameLabel -> 
  {{Style[Subscript[f, 2][y], 16], ""}, {Style[Subscript[f, 1][x], 16], ""}}]}, 
 Spacer[10]]

enter image description here

$\endgroup$

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.