# How to control the positions of contour labels?

ContourPlot[x^2 + 5 y^2, {x, -5, 5}, {y, -2, 2},
Contours -> {2, 4, 6, 8, 10, 12, 14, 16, 20},
ContourLabels -> True,
AspectRatio -> Automatic,


gives result

But I want result like this

So I hope this code will work

ContourPlot[x^2 + 5 y^2, {x, -5, 5}, {y, -2, 2},
Contours -> {2, 4, 6, 8, 10, 12, 14, 16, 20},
ContourLabels -> (Text[#3, {#1, 0}, Background -> White] &),
AspectRatio -> Automatic,


But it didn't, it gives result

So how to control the position of ContourLabels?

• None of the workarounds offered in the answers (so far) explains why ContourPlot is giving the wrong coordinate for 14. What am I missing? – rhermans Sep 11 '14 at 9:20
• @rhermans - Unlike for the other labels, the default location for the label 14 is far from the x=0 (semi-major) axis so that when its y coordinate is just changed to zero without also correcting the x coordinate it ends up in the wrong position. The problem is not with ContourPlot but rather with the manual positioning of that label. – Bob Hanlon Sep 11 '14 at 12:32
• @Bob_Hanlon, thanks for the explanation. – rhermans Sep 11 '14 at 12:34

This can done with Epilog.

f[x_, y_] := x^2 + 5 y^2;
contours = {2, 4, 6, 8, 10, 12, 14, 16, 20};
lblXY = {#, 0} & /@ (Solve[f[x, 0] == #, x][[2, 1, 2]] & /@ contours // N);

ContourPlot[f[x, y], {x, -5, 5}, {y, -2, 2},
Contours -> contours,
AspectRatio -> Automatic,
Epilog -> {Thread[Text[contours, lblXY, Background -> White]]}]


Kind of a hack but this is what I would do.

f[x_, y_] := x^2 + 5 y^2;
c = {2, 4, 6, 8, 10, 12, 14, 16, 20};
labelPos = Solve[f[x, 0] == #, x][[2, 1, 2]] & /@ c;

Show[
ContourPlot[f[x, y], {x, -5, 5}, {y, -2, 2}, Contours -> c,
AspectRatio -> Automatic, ContourShading -> None],
Graphics[Text[#[[2]], {#[[1]], 0}, {0, 0}, Background -> White]] & /@
Transpose[{labelPos, c}]
]


Yes another workaround

Show@{ContourPlot[x^2 + 5 y^2, {x, -5, 5}, {y, -2, 2},
Contours -> Range[2, 20, 2], AspectRatio -> Automatic,
ContourShading -> None, ImageSize -> 640],
ContourPlot[x^2 + 5 y^2, {x, 0, 5}, {y, -0.0001, 0.0001},
Contours -> Range[2, 20, 2],
ContourLabels -> (Text[#3, {#1, #2}, Background -> White] &),


I decrease the possible region for labels by the second ContourPlot.

f = x^2 + 5 y^2;
ContourPlot[f, {x, -5, 5}, {y, -2, 2},
Contours -> {2, 4, 6, 8, 10, 12, 14, 16, 20},
ContourLabels -> (Text[#3, {Max[x /. Solve[f == #3 /. y -> 0, x]], 0},
Background -> White] &),
AspectRatio -> Automatic, ContourShading -> None]


Use

ContourLabels -> (Text[#3,  Max[x /. Solve[(f /. y -> x/3) == #3, x]] {1, 1/3},
Background -> White] &)


to get

Update: you can also post-process the ContourPlot output to modify the location of the labels:

cp = ContourPlot[x^2 + 5 y^2, {x, -5, 5}, {y, -2, 2},
Contours -> {2, 4, 6, 8, 10, 12, 14, 16, 20}, PlotPoints -> 200,
ContourLabels -> Automatic, AspectRatio -> Automatic,

labelfunction := (Shift = RandomReal[{-30, 30}];