Plot the distribution curve

How to draw a distribution curve? such as a normal distribution,
its format is:

Distributions.Normal{Float64}(μ=-0.42117172154916505, σ=1.2253594150160463)

thanks!

I assume you mean to plot the curve of PDF

using Plots, Distributions

julia> L = Normal(1, 1)
Normal{Float64}(μ=1.0, σ=1.0)

julia> plot(x->pdf(L, x))

I actually have a lot of distributions, do you know how to plot them as below?

Thank you very much!

10-element Vector{Normal{Float64}}:
Normal{Float64}(μ=-0.42117172154916505, σ=1.2253594150160463)
Normal{Float64}(μ=1.4244177594878171, σ=1.2253594150160463)
Normal{Float64}(μ=-0.7646882557011875, σ=1.2253594150160463)
Normal{Float64}(μ=-1.4994608515495296, σ=1.2253594150160463)
Normal{Float64}(μ=0.1588834413196244, σ=1.2253594150160463)
Normal{Float64}(μ=0.6906462431515679, σ=1.2253594150160463)
Normal{Float64}(μ=-0.8610106914769075, σ=1.2253594150160463)
Normal{Float64}(μ=0.39571181451559956, σ=1.2253594150160463)
Normal{Float64}(μ=-0.7506648963208741, σ=1.2253594150160463)
Normal{Float64}(μ=1.0347673088571538, σ=1.2253594150160463)

why would this change anything? You just plot one line for each of them. Essentially with pdf, you can get xs and ys for each of them.

If you want ridge line plot, see:
https://kristofferc.github.io/PGFPlotsX.jl/stable/examples/gallery.html#D-Waterfall

1 Like

Ok, thank you very much!!

using Random
using Distributions

Random.seed!(42)
#Generate Data
x_min = -10 # xrange to plot
x_max = 10
μ_min = -5
μ_max = 5

dist = (μ, σ) -> Normal(μ, σ)
# make the set of distributions we're going to plot:
dists = [dist(-6+i, 1+0.3*i) for i in 1:10]
# creates random scatter points:
rnd = rand.(Truncated.(dists, x_min, x_max), 20)
# get the pdf of the dists:
dat_pdf = [(x) -> pdf.(d, x) for d in dists]

# point density for pdfs
x_pnts = collect(x_min:0.05:x_max)

# add redundant points at the ends, for nicer fill:
x_pnts_ext = [[x_pnts[1]]; x_pnts; [x_pnts[end]]]

# define the Axis to which we will push! the contents of the plot
axis = @pgf Axis(
    {
        width = raw"1\textwidth",
        height = raw"0.6\textwidth",
        grid = "both",
        xmax = x_max,
        xmin = x_min,
        zmin = 0,
        "axis background/.style" = { fill = "gray!10" }, # add some beauty
        # this is needed to make the scatter points appear behind the graphs:
        set_layers,
        view = "{49}{25}",   # viewpoint
        ytick = collect(0:9),
        ztick = collect(0:0.1:1)
    },
)

# draw a yellow area at the bottom of the plot, centered at μ and 2σ wide.
@pgf area = Plot3(
    {
        no_marks,
        style ="{dashed}",
        color = "black",
        fill = "yellow!60",
        fill_opacity = 0.65,
        # so we can see the grid lines through the colored area:
        on_layer = "axis background"
    },
    Table(x = [dists[1  ].μ - dists[1  ].σ, dists[end].μ - dists[end].σ,
               dists[end].μ + dists[end].σ, dists[1  ].μ + dists[1  ].σ],
          y = [length(rnd) - 1, 0, 0, length(rnd) - 1],
          z = [0, 0, 0, 0]
         ),
    raw"\closedcycle"
)
push!(axis, area)

# add the slices as individual plots to the common axis
@pgf for i in eachindex(dists)
    scatter = Plot3(
        {
            only_marks,
            color = "red!80",
            mark_options = {scale=0.4},
            # set the markers on the same layer as the plot:
            mark_layer = "like plot",
            on_layer = "axis background"
        },
        Table(x = rnd[i],
              y = (length(dists) - i) * ones(length(rnd[i])),
              z = zeros(length(rnd[i])))
    )
    push!(axis, scatter)

    # add a pdf-curve on top of each second data set
    if i%2 == 1
        curve = Plot3(
            {
                no_marks,
                style = {thick},
                color = "blue"
            },
            Table(x = x_pnts,
                  y = (length(dists) - i) * ones(length(x_pnts)),
                  z = dat_pdf[i](x_pnts))
        )

        # The fill is drawn seperately to handle the the end of the curves nicely.
        # This is an alternative to "\fillbetween"
        fill = Plot3(
            {
                draw = "none",
                fill = "blue",
                fill_opacity = 0.25
            },
            Table(x = x_pnts_ext,
                  y = (length(dists) - i) * ones(length(x_pnts_ext)),
                  z = [[0]; dat_pdf[i](x_pnts); [0]])
        )
        push!(axis, curve, fill)
    end
end

I am running this example in pgfplotsx.jl with an error:
ERROR: LoadError: MethodError: no method matching Table(; x=[-6.3, 0.0, 8.0, -3.7], y=[9, 0, 0, 9], z=[0, 0, 0, 0])
Closest candidates are:
Table(::Type…) at C:\Users\dell.julia\packages\ScientificTypesBase\QLxNe\src\ScientificTypesBase.jl:144 got unsupported keyword arguments “x”, “y”, “z”
Stacktrace:
[1] top-level scope
@ untitled-f6199b5ecb0eccd481cb1cf366825034:44
[2] eval
@ .\boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
@ Base .\loading.jl:1116
in expression starting at untitled-f6199b5ecb0eccd481cb1cf366825034:44
LoadError: MethodError: no method matching Table(; x=[-6.3, 0.0, 8.0, -3.7], y=[9, 0, 0, 9], z=[0, 0, 0, 0])
Closest candidates are:
Table(::Type…) at C:\Users\dell.julia\packages\ScientificTypesBase\QLxNe\src\ScientificTypesBase.jl:144 got unsupported keyword arguments “x”, “y”, “z”
Stacktrace:
[1] top-level scope
@ untitled-f6199b5ecb0eccd481cb1cf366825034:44
[2] eval
@ .\boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
@ Base .\loading.jl:1116
in expression starting at untitled-f6199b5ecb0eccd481cb1cf366825034:44

Plots.jl examples

First example:

using Distributions
using Plots

Distributions.Normal{T}(; μ, σ) where T = Normal{T}(μ, σ)
normals = [
    Normal{Float64}(μ=-0.42117172154916505, σ=1.2253594150160463)
    Normal{Float64}(μ=1.4244177594878171, σ=1.2253594150160463)
    Normal{Float64}(μ=-0.7646882557011875, σ=1.2253594150160463)
    Normal{Float64}(μ=-1.4994608515495296, σ=1.2253594150160463)
    Normal{Float64}(μ=0.1588834413196244, σ=1.2253594150160463)
    Normal{Float64}(μ=0.6906462431515679, σ=1.2253594150160463)
    Normal{Float64}(μ=-0.8610106914769075, σ=1.2253594150160463)
    Normal{Float64}(μ=0.39571181451559956, σ=1.2253594150160463)
    Normal{Float64}(μ=-0.7506648963208741, σ=1.2253594150160463)
    Normal{Float64}(μ=1.0347673088571538, σ=1.2253594150160463)
] |> x -> sort(x; by=mean)

ys = range(-10, 10; length=300)
m, n = length(normals), length(ys)
plot(legend=false)
for (x, normal) in zip(range(-1.5, 1.5; length=m), normals)
    plot3d!(fill(x, n), ys, pdf.(normal, ys))
end
plot!()

Second example (linear regression):

using LinearAlgebra
using Distributions
using Plots

dist_true = MvNormal([50, 50], 25^2*[1 1; 1 1.3])
n = 30
sample = rand(dist_true, n)
x, y = sample[1,:], sample[2,:]
X = x .^ (0:1)'
b̂ = X\y # b\hat TAB -> b̂
ŷ = X*b̂
u = norm(y - ŷ)/√(n - 2)
f(x) = evalpoly(x, b̂)
s(x) = u*√(1 + dot([1, f(x)], X'X\[1, f(x)]))
#disty(x) = Normal(f(x), s(x))
disty(x) = LocationScale(f(x), s(x), TDist(n-2))

plot(legend=false, xtick=-100:50:200, ytick=-100:50:200)
for xs in 0:10:100
    ys = range(-50, 150; length=200)
    plot3d!(fill(xs, length(ys)), ys, pdf.(disty(xs), ys))
end
scatter3d!(x, y, zeros(n); ms=2, msc=:auto, color=:red)
xs = range(-30, 130; length=100)
plot3d!(xs, f.(xs), zero(xs); color=:blue)

3 Likes