# Ghosting on contour plots of a (x,y)→Bool function

**URL:** <https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110>\
**Category:** Visualization\
**Tags:** plotting\
**Created:** [June 17, 2021, 7:08pm UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110 "2021-06-17T19:08:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![owiecc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/owiecc/32/8894_2.png) [@owiecc](https://discourse.julialang.org/u/owiecc)\
**Post date:** [June 17, 2021, 7:08pm UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110/1 "2021-06-17T19:08:15Z")

</div>

I would like to plot of a `(x,y) → Bool` function as a contour plot. For the function I am plotting I get a lot of ghosting. The closer to 45° the line is the better it looks. Compare the heatmap to the contour plots:

 ![heatmap](https://global.discourse-cdn.com/julialang/original/3X/0/1/01b7f9401d67199efc8c9816d1daf79db4ec601a.png)

 ![contour](https://global.discourse-cdn.com/julialang/original/3X/1/0/1070db552f4290147fac6b09e784ab5e34c5ecec.png)

Do you have any tips on how I can get the contour plotting done reliably? Is there a better way to plot contours and boundaries? Ideally, I’d like to get a nice vector plots with lines on the boundaries.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 17, 2021, 11:09pm UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110/2 "2021-06-17T23:09:04Z")

</div>

The following seems to improve things:

```julia
using Plots; gr()

boolxy(x,y) = (y>0.6-1e-3*x) & (y>5e-4*x-0.1) & (y>0.2) ? false : true

x, y = LinRange(0,900,500), LinRange(0,0.5,500)
plot(heatmap(x,y,boolxy,legend=false), contour(x,y,boolxy,levels=[0.01],legend=false), dpi=300)

```

 ![Plots_gr_contour_boolean_fxy](https://global.discourse-cdn.com/julialang/original/3X/a/f/afafaf718cd33ca908fb6e22488b9f41105bd37e.png)

---

<div class="post-metadata">

**Author:** ![owiecc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/owiecc/32/8894_2.png) [@owiecc](https://discourse.julialang.org/u/owiecc)\
**Post date:** [June 18, 2021, 7:06am UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110/3 "2021-06-18T07:06:11Z")

</div>

I have no clue how you found this combination. Inverting my function, like you do, helps somewhat. Adding the level at 0.01 makes the lines darker.

 ![contour2](https://global.discourse-cdn.com/julialang/original/3X/1/2/1253e45939c023b218f00a38d5b2f2c1532d9c6d.png)

Still not perfect but sooo much better. Thanks @rafael.guerra

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 18, 2021, 7:22am UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110/4 "2021-06-18T07:22:35Z")

</div>

@owiecc, the following workflow with a grain of ImageFiltering seems to be more robust, not requiring negating the boolean function, nor tuning the contour level between 0 and 1:

```julia
using Plots; gr()

boolxy(x,y) = (y>0.6-1e-3*x) & (y>5e-4*x-0.1) & (y>0.2) ? true : false

x, y = LinRange(0,900,1000), LinRange(0,0.5,1000)
z = [boolxy(x,y) for y in y, x in x]

using ImageFiltering
kern1 = centered([1/3, 1/3, 1/3])
kernf = kernelfactors((kern1, kern1))
w = imfilter(z, kernf)
plot(heatmap(x,y,w), contour(x,y,w,levels=[0.5]), colorbar=false,dpi=300)

```

 ![Plots_gr_contour_boolean_fxy_ImageFiltering](https://global.discourse-cdn.com/julialang/original/3X/1/3/1370894edce166ec7023cff41c8bfa2ce7d18868.png)

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 18, 2021, 9:58am UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110/5 "2021-06-18T09:58:18Z")

</div>

If the equations for the mask boundaries are available as in code above, then it might be preferable to plot them directly:

```julia
using Plots; gr()

l1(x) = 0.6-1e-3*x 
l2(x) = 5e-4*x-0.1
l3(x) = 0.2
bool1(x) = begin y=l1(x); (y>=l2(x)) & (y>=l3(x)) ? y : NaN; end
bool2(x) = begin y=l2(x); (y>=l1(x)) & (y>=l3(x)) ? y : NaN; end
bool3(x) = begin y=l3(x); (y>=l1(x)) & (y>=l2(x)) ? y : NaN; end

x = LinRange(0,900,100)
yy = @. [bool1(x); bool2(x); bool3(x)]
xx = [x; x; x]
zz = [xx yy]
nanr = isnan.(zz[:,2])
zz = zz[.!vec(nanr), :]
zz = sortslices(zz,dims=1,by=x->x[1])
plot(zz[:,1],zz[:,2]; lc=:black,legend=false,xlims=(0,900),ylims=(0,0.5), dpi=300)

```

 ![Plots_gr_contour_boolean_individual_functions](https://global.discourse-cdn.com/julialang/original/3X/9/0/90b607098fe16cff20a37dc86abc6ad5e62d502d.png)

---

<div class="post-metadata">

**Author:** ![owiecc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/owiecc/32/8894_2.png) [@owiecc](https://discourse.julialang.org/u/owiecc)\
**Post date:** [June 18, 2021, 12:02pm UTC](https://discourse.julialang.org/t/ghosting-on-contour-plots-of-a-x-y-bool-function/63110/6 "2021-06-18T12:02:03Z")

</div>

Unfortunately the function comes from some funky transformations so I don’t know the boundary equations. But I like the solution with the blur filter. I guess it makes it easier for the contour algorithm to trace the edges if the function is a bit smoother.
