# Add gradient to ribbon based on density

**URL:** <https://discourse.julialang.org/t/add-gradient-to-ribbon-based-on-density/62081>\
**Category:** General Usage\
**Tags:** plotting, plots, distributions\
**Created:** [May 30, 2021, 11:04am UTC](https://discourse.julialang.org/t/add-gradient-to-ribbon-based-on-density/62081 "2021-05-30T11:04:25Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [May 30, 2021, 11:04am UTC](https://discourse.julialang.org/t/add-gradient-to-ribbon-based-on-density/62081/1 "2021-05-30T11:04:26Z")

</div>

Suppose I have a time series plot, such as:

```julia
using Plots 
t = 0:.1:10
n = length(t)
m = sin.(t)
y = m + randn(n) * .3
plot(t, m)
scatter!(t, y)

```

How can I add a gradient to the alpha value of the ribbon based on the density at each value along the x-axis? An example of what I am trying to accomplish can be found [here](https://stackoverflow.com/questions/37326686/ggplot2-geom-ribbon-with-alpha-dependent-on-data-density-along-y-axis-for-each).

---

<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:** [August 22, 2021, 9:08pm UTC](https://discourse.julialang.org/t/add-gradient-to-ribbon-based-on-density/62081/2 "2021-08-22T21:08:04Z")

</div>

This is an attempt to reproduce your example using Plots.jl and to learn Julia:

 ![Plots_normal_distributed_cloud_density_plot](https://global.discourse-cdn.com/julialang/original/3X/7/4/74234e06c5ae6527ca232374f34c23deb69b7f82.jpeg)

```julia

using Distributions, SmoothingSplines, Plots; gr()

f(x) = sin(x) # baseline function for this example

# GENERATE INPUT DATA:
σy = 1.0 # stdev relative to curve f(x)
npoints = 100
nsamples = 50
X = vcat([rand(Uniform(0, 4π), npoints) for _ in 1:nsamples]...)
Y = @. f.(X) + rand(Normal(0, σy*abs(cos(X))+0.1)) # variable stdev

# FIT NORMAL DISTRIBUTIONS WITH PARAMETERS: μ(x) and σ(x)
nx = 100; # number of divisions of x-axis to estimate distribution
x = LinRange(0, 4π, nx)
xᵢ = [(x[i], x[i+1]) for i in 1:length(x)-1]
x₀ = mean.(xᵢ)
μ = similar(x₀); σ = similar(x₀)
for (i,xᵢ) in pairs(xᵢ)
    ix = xᵢ[1] .<= X .<= xᵢ[2]
    h = fit(Normal, Y[ix])
    μ[i] = h.μ; σ[i] = h.σ
end

# FIT SMOOTHING SPLINES TO ABOVE
using SmoothingSplines
splμ = fit(SmoothingSpline,x₀, μ, 0.05) # λ=0.05
splσ = fit(SmoothingSpline,x₀, σ, 0.02) # λ=0.02
μp = SmoothingSplines.predict(splμ, x₀)
σp = SmoothingSplines.predict(splσ, x₀)

# PLOT DATA:
p1 = scatter(X,Y, ms=1, msw=-0, mc=:blue, label=false)
plot!(f, lc=:cyan, lw=1.5, label="sin(x) baseline")
plot!(x₀, μ, lc=:red, lw=1, ls=:dash, label="mean μ(x)")
plot!(x₀, σ, lc=:lime, lw=1, ls=:dash, label="stdev σ(x)")
plot!(x₀, μp, lc=:red, lw=1, label="spline μp(x)")
plot!(x₀, σp, lc=:lime, lw=1, label="spline σp(x)")

# PLOT RIBBONS WITH ALPHA TRANSPARENCY SCALED:
N = 300 # number of ribbon slices
qq = @. quantile(Normal(μp, σp), LinRange(0.01, 0.99,N))
α = [LinRange(0.01,0.4,N÷2); LinRange(0.4,0.01,N÷2)]
p2 = plot(legend=false)
for i in 2:N-1
    yᵢ = getindex.(qq, i)
    dy = yᵢ - getindex.(qq, i-1)
    plot!(x₀, yᵢ - dy/2, lw=0, color=:blue, fillalpha=α[i], ribbon=dy)
end
scatter!(X,Y, ms=1, msw=-0, mc=:darkblue, label=false)

plot(p1, p2, size=(1200,600), dpi=300, widen=false)

```

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [August 23, 2021, 11:01am UTC](https://discourse.julialang.org/t/add-gradient-to-ribbon-based-on-density/62081/3 "2021-08-23T11:01:30Z")

</div>

Looks good. Thanks!
