# Change Contour Plot Overlap Ordering

I have a contour plot for which I have selected a finite set of contours. However, the contours overlap in some places and I would like to reverse the order in which they are drawn.

In other words, the last contour (with the largest function value) is currently drawn on bottom, but I would like this contour to be on top. It is confusing for the contour with the largest value to be drawn as if it is beneath the others.

I have struggled to come up with a simple Minimal Working Example which includes contours which actually overlap, so here is my current MWE:

list = {0.25, 0.3, 0.5, 0.7, 0.8}; t = 0.01;
gray = 0.8; styles = {{GrayLevel[gray], Thickness[t]}, {GrayLevel[3/4 gray],Thickness[t]}, {GrayLevel[2/4 gray], Thickness[t]}, {GrayLevel[1/4 gray], Thickness[t]}, {GrayLevel[0], Thickness[t]}};

ContourPlot[Sqrt[x^2 + y^2], {x, -1, 1}, {y, -1, 1}, Contours -> list, ContourStyle -> styles] /. _Polygon -> Sequence[]


The only "problem" with this MWE is I couldn't devise a "simple" function for which the contours overlapped.

However, when I perform this same code for my real (more complex problem) the 100% black line you see in the MWE would be drawn as if on the bottom, and the smaller value (gray) contours are drawn on top.

I have tried to simply apply

list=Reverse[list];


after defining "list" before ContourPlot, but this does not correct the issue.

What can I do to fix this problem?

Lastly, here is an example image from one of my plots that illustrates the gray line (with smaller value) drawn atop the 100% black line (with larger value)

• Apparently Mathematica always draws contours in increasing order of function value. The easiest solution I can think of is to plot the negative of the function, ContourPlot[-Sqrt[...], ..., Contours -> -list].
– user484
Commented Jan 13, 2016 at 21:21

One way to do this is to create each contour separately, that then combine them via Show, which respects order. To illustrate:

Show@Table[
ContourPlot[
Sqrt[y x^2 + y^2]/(x y + 1) == list[[i]], {x, -1, 1}, {y, -1, 1},
ContourStyle -> styles[[i]],
{i, 1, Length@list}]


Show@Reverse@Table[
ContourPlot[
Sqrt[y x^2 + y^2]/(x y + 1) == list[[i]], {x, -1, 1}, {y, -1, 1},
ContourStyle -> styles[[i]],
{i, 1, Length@list}]


In the lower right corner where the contours overlap, the black line is on the top in the first plot and on the bottom in the second.

• Probably quite an elegant solution you have, but unfortunately I don't currently understand how it works well enough to generalize it to my expanded code. Is there a way to accomplish this without the pure function "#1 &," etc. stuff? Or can you help me understand how this works. Thanks! Commented Jan 14, 2016 at 17:37
• @Steve I've changed the code to use Table and explicitly plot a contour for each entry in list with ContourStyle given by the corresponding entry in styles. The pure function from before was doing the same thing, but this way is hopefully more transparent. Commented Jan 14, 2016 at 20:56
• Sadly, I guess it is my (your) MWE that is failing me. The MWE works, but in my plots the argument of ContourPlot is "Sort@Re@Eigenvalues[hamiltonian]" and for some reason the change from "Contours->list" to "==list[[i]]" does not work for this. Not sure if this practically a new problem altogether and I'd be forced to submit a new thread, but if you have any idea on how I could fix this, I would definitely appreciate it! Commented Jan 15, 2016 at 20:35
• @Steve do you mean list = Sort@Re@Eigenvalues[hamiltonian]? Commented Jan 16, 2016 at 2:58
• No, actually not. In my problem, hamiltonian is a matrix with 2 degrees of freedom which become the domain variables for the contour plot and the eigenvalue functional dependence on them is the function for which I take a contour plot. However, I have now made your solution work for me by simply using ",Contours->{list[[j]]}" and then making a table as you did. For some reason the "==list[[j]]" bit was not working for me. Either way, thank you very much for the help. Commented Jan 19, 2016 at 17:19

You can reverse the order of graphics elements too:

cp = ContourPlot[Sqrt[y x^2 + y^2]/(x y + 1), {x, -1, 1}, {y, -1, 1},
Contours -> list, ContourStyle -> styles, ContourShading -> None]


MapAt[Reverse, cp, {1, 2, 2}]


• I really like this solution because it seems the simplest minimal change to my existing code. However, I can get it to work as you did in your MWE, but it gives error in my real code. Can you help me understand the {1,2,2} arguments? I'm thinking maybe in my real code I might have more objects and need a 4-element list, etc. to solve it similarly? Commented Jan 14, 2016 at 17:32
• @Steve 1 is a GraphicsComplex in Graphics generated by plot, 2 is a second arg of that, which is a set of primitives, and the second there contains Lines we want to flip. It's semi manual so probably not the best approach. So basically find, where those lines are and map there.
– Kuba
Commented Jan 14, 2016 at 17:41

Another way (maybe not efficient way) is to trick the ContourPlot as follows:

ContourPlot[-Sqrt[y x^2 + y^2]/(x y + 1), {x, -1, 1}, {y, -1, 1},
Contours -> -list, ContourStyle -> Reverse@styles,
ContourShading -> None] /. Tooltip[x_, y_] :> Tooltip[x, -y]