# Add band around point scatter

**URL:** <https://discourse.julialang.org/t/add-band-around-point-scatter/16181>\
**Category:** General Usage\
**Tags:** plotting\
**Created:** [October 11, 2018, 1:39pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181 "2018-10-11T13:39:39Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 11, 2018, 1:39pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/1 "2018-10-11T13:39:39Z")

</div>

I have two datasets and I want to emphasize that one of them has smaller “noise level” than the other one. For example:

```julia
pts1_x = [10randn() for i = 1 : 100]
pts1_y = pts1_x.^2 .+ [100randn() for i = 1:100]
pts2_x = [10randn() for i = 1 : 100]
pts2_y = pts2_x.^2 .+ [25randn() for i = 1:100]

plt = Plots.plot()
Plots.scatter!(pts1_x, pts1_y)
Plots.scatter!(pts2_x, pts2_y)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/0/9/0990765f4b22572de0b3d31f785502a92ddf92cf.png)

To emphasize that the orange points have a smaller scatter around the parabola, I want to superpose a semi-transparent orange band around them, and a wider semi-transparent blue band around the blue points.

Note that in general, I do not know the law generating the points (i.e., that there is an underlying parabola). I just have two sets of points, one of which has a narrower distribution and I want to emphasize this.

Any suggestions on how to make this more visually obvious? Thanks!

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 11, 2018, 1:45pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/2 "2018-10-11T13:45:09Z")

</div>

Perhaps compute the ~~complex~~ convex hull and then apply some smoothing to make it look nicer.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 11, 2018, 1:53pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/3 "2018-10-11T13:53:58Z")

</div>

> [@kristoffer.carlsson](#):
>
> Perhaps compute the complex hull and then apply some smoothing to make it look nicer.

You mean “convex hull”? I guess I can use [GitHub - JuliaPolyhedra/QHull.jl: A Julia wrapper around a PyCall wrapper around the qhull Convex Hull library](https://github.com/JuliaPolyhedra/QHull.jl) to compute it. Any suggestions on how to smooth it?

In reality I was hoping there would be a simpler way, like a magical option in Plots 😛

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2018, 1:54pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/4 "2018-10-11T13:54:39Z")

</div>

If you have access to the mean function/ true underlying function, you can plot it and use the keyword `ribbon` in Plots.jl to draw the transparent bands you are looking for.  
[http://docs.juliaplots.org/latest/attributes/](http://docs.juliaplots.org/latest/attributes/)  
See link above for attributes in Plots.jl

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 11, 2018, 1:56pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/5 "2018-10-11T13:56:23Z")

</div>

Another approach is to first estimate the underlying function from the points (how?), and then use `ribbon`.

To estimate the underlying function, I could do some moving average + interpolation. I have to think about this.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 11, 2018, 2:01pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/6 "2018-10-11T14:01:21Z")

</div>

> [@e3c6](#):
>
> You mean “convex hull”?

Haha yes!

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2018, 2:01pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/7 "2018-10-11T14:01:25Z")

</div>

It looks like a parabola, try

```julia
using Statistics
pts1_x = [10randn() for i = 1 : 100]
pts1_y = pts1_x.^2 .+ [100randn() for i = 1:100]
pts2_x = [10randn() for i = 1 : 100]
pts2_y = pts2_x.^2 .+ [25randn() for i = 1:100]

A = pts1_x.^(0:2)'
k = A\pts1_y # Estimate linear model of order 2

yhat = A*k

I = sortperm(pts1_x)
plt = Plots.plot()
Plots.scatter!(pts1_x, pts1_y)
Plots.scatter!(pts2_x, pts2_y)
Plots.plot!(pts1_x[I], yhat[I], ribbon = 2std(yhat-pts1_y))

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2018, 2:07pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/8 "2018-10-11T14:07:01Z")

</div>

Hmm, it seems there’s some issue with the `ribbon` keyword, the following produces a nice plot for me

```julia
pts1_x = [10randn() for i = 1 : 100]
pts1_y = pts1_x.^2 .+ [100randn() for i = 1:100]
pts2_x = [10randn() for i = 1 : 100]
pts2_y = pts2_x.^2 .+ [25randn() for i = 1:100]

A = pts1_x.^(0:2)'
k = A\pts1_y # Estimate linear model of order 2

yhat = A*k

I = sortperm(pts1_x)
plt = Plots.plot()
Plots.scatter!(pts1_x, pts1_y, color=:orange)
Plots.scatter!(pts2_x, pts2_y, color=:blue)
Plots.plot!(pts1_x[I], yhat[I], fillrange = yhat[I].+2std(yhat-pts1_y), alpha=0.2, color=:orange)
Plots.plot!(pts1_x[I], yhat[I], fillrange = yhat[I].-2std(yhat-pts1_y), alpha=0.2, color=:orange)

```

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 11, 2018, 2:08pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/9 "2018-10-11T14:08:53Z")

</div>

The parabola was just an example. The real data is more complicated.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2018, 2:10pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/10 "2018-10-11T14:10:14Z")

</div>

Then a heavily lowpass-filtered signal might work better. Check DSP.jl for filtering options.

---

<div class="post-metadata">

**Author:** ![galenlynch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/galenlynch/32/17947_2.png) [@galenlynch](https://discourse.julialang.org/u/galenlynch)\
**Post date:** [October 11, 2018, 2:28pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/11 "2018-10-11T14:28:57Z")

</div>

FWIW I think the scatter by itself is pretty clear. When you say that one has a narrower distribution, you mean a narrower distribution around a varying local mean, right? One way to do accomplish your goal would be to bin your data points in the x dimension, and construct the band based on the quantiles in those bins.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 11, 2018, 2:40pm UTC](https://discourse.julialang.org/t/add-band-around-point-scatter/16181/12 "2018-10-11T14:40:41Z")

</div>

The parabolic scatter is just an example. I have more complicated datasets that would benefit from better visualization.
