7
$\begingroup$

I wish to plot 2 functions $f$ and $g$ so that the region bounded by $f$ has color $c_f$, the region bounded by $g$ has color $c_g$, and the region bounded by both has color $c_f+c_g$. E.g. $c_f$ is red, $c_g$ is blue, $c_f+c_g$ is magenta.

I tried this:

Plot[{Sin[x], Cos[x]}, {x, -π, +π}, Filling -> {1 -> {Axis, Blue}, 2 -> {Axis, Red}}]

bad

I found no documentation on how to do additive mixture of colors in a plot. How can I do so?

$\endgroup$

3 Answers 3

3
$\begingroup$

A simple approach would be to plot a third function which defines the overlap region.

overlap[f_List] := Piecewise[{{Sign[First@f] Min[Abs@f], Equal @@ Sign[f]}}, I]

Plot[{Sin[x], Cos[x], overlap[{Sin[x], Cos[x]}]}, {x, -π, π},
 Filling -> {1 -> {0, Blue}, 2 -> {0, Red}, 3 -> {0, Thread[Red + Blue, RGBColor]}}]

enter image description here

$\endgroup$
4
  • $\begingroup$ Thanks. It's a slight kludge, but it works. I actually defined overlap thus: overlap[x_, y_] := UnitStep[Sign[x] Sign[y]] Sign[x] Min[Abs[x], Abs[y]] $\endgroup$ Nov 24, 2013 at 15:41
  • $\begingroup$ @strake: For two functions the easiest thing to do might be Median[{x, y, 0}]. $\endgroup$
    – user484
    Nov 24, 2013 at 16:50
  • $\begingroup$ @RahulNarain, that's clever. $\endgroup$ Nov 24, 2013 at 16:53
  • $\begingroup$ @RahulNarain Thanks, that's much neater. $\endgroup$ Dec 10, 2013 at 19:36
4
$\begingroup$

One easy way will be to use Opacity!

Plot[{Sin[x], Cos[x]}, {x, -\[Pi], +\[Pi]},
Filling -> {1 -> {Axis, Directive[Opacity[.7], Blue]},
2 -> {Axis, Directive[Opacity[.7], Red]}}]

enter image description here

Update: Here comes a better solution for your problem. The function is pretty much self explanatory as far as the argument names are concerned. Given a list of functions to be plotted together we take any one of them and use Plot to sample this function. Then we do a condition check on the sample to find the x-coordinates for the common region. We do a ListLinePlot for this common region and use Show to display it on the default plot.

UnionPlot[funs_, samplingFunction_, {start_, end_}, fillingUnion_, 
  plot_, plotPoints_: 600, maxRecursion_: 4] := 
 Block[{union, sample, fun},
  union = 
   If[And @@ (#[x] <= 0 & /@ ##), Evaluate@(Max @@ (#[x] & /@ ##)), 
      If[And @@ (#[x] > 0 & /@ ##), Evaluate@(Min @@ (#[x] & /@ ##)), 
       0]] &@funs;
  sample = (First@Cases[Plot[Evaluate[funs[[samplingFunction]][x]],
  {x, start, end},PlotPoints -> plotPoints, MaxRecursion -> maxRecursion], 
       Line[a___] :> a, Infinity])[[All, 1]]; 
  fun = Function[x, Evaluate@union];
  Show[plot, 
   ListLinePlot[Transpose@{sample, fun[#] & /@ sample}, 
    Filling -> Axis, PlotRange -> All, InterpolationOrder -> 1, 
    Evaluate@fillingUnion, Axes -> False]]
  ]

Usage:

Lets take a list of functions to be plotted and define a FillingStyle for the common region!

funs = {Sin[3 #] &, Cos[4 #] &, .8 Sin[2 #]^2 Cos[3 #] &};
commonfillingStyle = FillingStyle -> Blend[{Red, Blue, Green}, .3];

Now we will use the 3rd function to sample the x-coordinate of our plot.

UnionPlot[funs, 3, {-Pi, Pi}, commonfillingStyle, 
 Plot[Evaluate[#[x] & /@ funs], {x, -Pi, Pi}, 
  Filling -> {1 -> {Axis, None}, 2 -> {Axis, Red},3 -> {Axis, Orange}}]]

enter image description here

Your example case with commonfillingStyle = FillingStyle -> Blend[{Red, Blue}, .5] becomes the following.

enter image description here

$\endgroup$
3
  • $\begingroup$ Not additive mixture; try swapping the colors. I tried this with my actual functions and it was unreadable. $\endgroup$ Nov 23, 2013 at 23:21
  • $\begingroup$ @strake Check the update! Tell me if this solves your problem. $\endgroup$ Nov 24, 2013 at 2:18
  • $\begingroup$ Unfortunately I'm not quite sure how to use this in my case. I tried to rewrite the plotted expression as a function evaluation but failed. $\endgroup$ Nov 24, 2013 at 4:51
1
$\begingroup$

Using Region Functionality:

Clear["Global`*"];
funcs = {Sin[x + π/4], Cos[x]};
overlap = 
  ImplicitRegion[
   y > 0 && y <= funcs[[1]] && y < funcs[[2]] || 
    y < 0 && y >= funcs[[1]] && y >= funcs[[2]], {{x, -π, π}, 
    y}];

p1 = Plot[funcs, {x, -π, π}
   , PlotStyle -> {Blue, Red}
   , Filling -> {
     {1 -> {Axis, Directive[Blue, HatchFilling[1, 3, 6]]}}
     , {2 -> {Axis, Directive[Red, HatchFilling[2, 3, 6]]}}}
   , PlotLegends -> "Expressions"
   ];

p2 = RegionPlot[overlap
   , PlotStyle -> Directive[Opacity[1, Lighter@Lighter@Purple]]
   , BoundaryStyle -> Directive[Purple, Thick]
   , PlotLegends -> "AllExpressions"
   ];

Show[p1, p2]

enter image description here

$\endgroup$
1
  • $\begingroup$ p1 would be able to show the overlapping regions for display purposes only. Regions can also be used to do calculations. $\endgroup$
    – Syed
    Feb 6 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.