# 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? 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. Sep 11 '14 at 12:32
• @Bob_Hanlon, thanks for the explanation. 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[#[], {#[], 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,

Normal[cp] /. Tooltip[a_, b_] :> {a,
Text[Style[b, 16],
Nearest[{1, 2 GoldenRatio} # & /@ a[[-1, 1]], {.5, 0}, 1][],
Background -> White]} I liked the answer, where the labels were printed on the diagonal, but such placing can often lead to overlapping of some labels, so, I modified it to add random shifts: (the example is in my context)

labelfunction := (Shift = RandomReal[{-30, 30}];
Text[#3, {e, 100 - e/3 + Shift} /.FindRoot[(ff - #3, {e,100}]]) & ;
ContourPlot[... , ContourLabels -> labelfunction]