4
$\begingroup$

The default ordering is "in the y direction". In this example I would like the red regions to overlay the blue regions.

    Plot[{0, 0.6 a, a, 0.4 + 0.6 a, 0.6 (1 - a), 1 - a, 1 - 0.6 a, 1}, {a,0, 1}, Filling -> {1 -> {{2}, Red}, 3 -> {{4}, Blue}, 5 -> {{6}, Blue},7 -> {{8}, Red}, 1 -> {{2}, Red}}]

In my actual code I have a dozen or so regions.

$\endgroup$
5
$\begingroup$

This is hacky, this might not work in your real case, but you could switch positions of polygons that are red/blue when, blue is in front of red. You have to repeat the replacement until there is no change

gr = Plot[{0, 0.6 a, a, 0.4 + 0.6 a, 0.6 (1 - a), 1 - a, 1 - 0.6 a, 1}, 
{a, 0, 1}, 
  Filling -> {1 -> {{2}, Red}, 3 -> {{4}, Blue}, 5 -> {{6}, Blue}, 
    7 -> {{8}, Red}, 1 -> {{2}, Red}}];

gr //. {start__, blue : {EdgeForm[], RGBColor[0, 0, 1], __}, {} ..., 
   red : {EdgeForm[], RGBColor[1, 0, 0], __}, end__} :> {start, red, blue, end}

Mathematica graphics

Edit

Let me elaborate a bit. First, I think I reordered your colors the wrong way. You said "the red regions [should] overlay the blue regions" which I'm doing the other way around.

Additionally, I only gave an example when there is Blue as only other color. Probably, you have many different colors. So here is a version that does it correctly and can handle different colors

gr = Plot[{0, 0.6 a, a, 0.4 + 0.6 a, 0.6 (1 - a), 1 - a, 1 - 0.6 a, 
   1}, {a, 0, 1}, 
  Filling -> {1 -> {{2}, Red}, 3 -> {{4}, Green}, 5 -> {{6}, Blue}, 
    7 -> {{8}, Red}, 1 -> {{2}, Red}}];
gr //. {start__, red : {EdgeForm[], RGBColor[1, 0, 0], __}, {} ..., 
   other : {EdgeForm[], Except[RGBColor[1, 0, 0], RGBColor[__]], __}, 
   end__} :> {start, other, red, end}

Mathematica graphics

The trick is to use a pattern Except[RGBColor[1, 0, 0], RGBColor[__]] that matches all colors except of Red.

You see that in the image above there are only the faces of the polygons corrected. The lines are still drawn. You can fix this too by simply investigating in the structure of your plot. Therefore, take a look at InputForm[gr] and scroll past all the coordinates.

What you will find is exactly the structure I used where every surface is represented as a list {EdgeForm[], RGBColor...}. I did nothing more that to look at this and to create a rule that does the transformation you wanted.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks for your speed of response, halirutan, but I am not expert enough to understand your solution (though I have nothing against "hacky"). And, in my case the regions are not "polygons" because the lines are really polynomial rather than linear. $\endgroup$ – MikeP Sep 9 '15 at 12:25
  • $\begingroup$ A few minutes later! Your solution seems to work, provided I switch red and blue in your code, even when my lines are polynomial. I would need to understand the syntax and logic of your hack to see if I can apply it to my rather more complicated diagram which has around 6 colours, a dozen lines and about 20 regions. Can you instruct me, please? $\endgroup$ – MikeP Sep 9 '15 at 12:39
  • $\begingroup$ @MikeP Please look at the edit of my answer. With this, you don't need to do it for every color, because the rule just pushes red to the background, no matter what other colors you have there.. $\endgroup$ – halirutan Sep 9 '15 at 13:39
  • $\begingroup$ Just one more problem! I use some fillings like "Opacity[0.5, RGBColor[1., 0.9, 0.9]]" called say "mycolor". Is there a way of matching such forms, maybe by saying it is equal to or unequal to "mycolor" such that the script would handle RGBs as well as these? $\endgroup$ – MikeP Sep 9 '15 at 15:14
  • 1
    $\begingroup$ @MikeP Yes, of course there is a solution for this. You look at InputForm[gr] and check how your Opacity call translates into the graphics. You will find, that it is kept exactly as you wrote it. Therefore, you need to match both forms: Except[RGBColor[1, 0, 0], RGBColor[__] | Opacity[__]] $\endgroup$ – halirutan Sep 9 '15 at 15:53
4
$\begingroup$

It seems those drawn first are placed in the lowest layer, so you just need to re-arrange the order of your functions as following:

Plot[{
        a, 0.4 + 0.6 a,
        0.6 (1 - a), 1 - a,
        0, 0.6 a,
        1 - 0.6 a, 1
     }, {a, 0, 1}, 
     Filling -> {1 -> {{2}, Blue}, 3 -> {{4}, Blue},
                5 -> {{6}, Red}, 7 -> {{8}, Red}}
    ]

blue-first overlay

| improve this answer | |
$\endgroup$
  • $\begingroup$ I had expected that the order of the Filling command controlled the overlay but this does seem not to affect the output. Your suggestion that the order of line plotting is important is very useful. I will try to take advantage of this but I would need to know more as in my case a line may be the border between a region of top priority and one of bottom priority. How do you think the overlay order would work in such a case? Given an ordering of the lines, what would be the overlay order in general for the regions formed? I couldn't find any information on this. $\endgroup$ – MikeP Sep 9 '15 at 13:55
  • $\begingroup$ @MikeP It sounds like a combination optimization problem. Do you have a more realistic example? $\endgroup$ – Silvia Sep 9 '15 at 14:01
  • $\begingroup$ I think your suggestion has solved it, though not as elegantly as I would wish. All I may need to do is to use up to two copies of each line so that I can get the boundaries of the regions defined in the order I want. E.g. Plot[{1, x, 1/2 - x, 3/2 - x, 0, x}, {x, 0, 1}, Filling -> {3 -> {{4}, Green}, 1 -> {{2}, Red}, 5 -> {{6}, Blue}}, PlotRange -> {0, 1}] (Sorry, I haven't figured out formatting yet!) $\endgroup$ – MikeP Sep 9 '15 at 14:12

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.