In [3]:
# Load in Plots.  Note that RecipesBase is loaded as well,
# and Plots will re-export the @recipe macro.
using Plots
pyplot(size=(400,250));

In [40]:
using Distributions
function default_range(dist::Distribution, n = 4)
    μ, σ = mean(dist), std(dist)
    linspace(μ - n*σ,μ + n*σ, 100)
end
dist = Normal(10,50)


Out[40]:
Distributions.Normal(μ=10.0, σ=50.0)

In [41]:
# Build a recipe which acts on a custom type.
# Notice that the function apply_recipe is returned.
# The recipe macro is just a convenience to build apply_recipe definitions.
@recipe function f(dist::Distribution, x = default_range(dist))
    y = map(xi -> pdf(dist,xi), x)
    seriestype --> :path  # there is always an attribute dictionary `d` available...
                          # If the user didn't specify a seriestype, we choose :path
    x, y
end


Out[41]:
apply_recipe (generic function with 46 methods)

In [42]:
# that was pretty easy!
plot(dist)


Out[42]:

In [43]:
# all the conveniences of Plots are available
plot(dist, -100:10:20, line=(3,:black,:dot), fill=(0,0.2,:red))


Out[43]:

In [44]:
# and we could just as easily do a different seriestype:
bar(dist, -200:10:100, bar_width=5, α=0.2)


Out[44]:

In [45]:
# and overlay other series... lets make a rug plot
scatter!(rand(dist, 100), [2e-4], marker=(10,0.5,:vline), ylim=(0,Inf))


Out[45]:

In [53]:
# We can accept custom keyword arguments.
# Lets re-define the recipe, and allow any function of dist and another variable.
@recipe function f(dist::Distribution, x = default_range(dist); func = pdf)
    func = pop!(d, :func)  # the keyword will appear in the attribute dictionary
                           # pop it out to avoid compliants later
    y = map(xi -> func(dist,xi), x)
    seriestype --> :path
    x, y
end


Out[53]:
apply_recipe (generic function with 46 methods)

In [57]:
plot(dist, func=cdf, fillrange=0.5, line=(3,:black))


Out[57]:

In [ ]: