In [7]:
using Plots
import Plots: _apply_recipe, KW

# this is a custom type that acts just like a Function
immutable F
   f::Function
end
getf(f::F) = f.f


Out[7]:
getf (generic function with 1 method)

In [8]:
# We add this type as a Plots recipe.  This hook is called after initial Plots
# preprocessing (replacing aliases and other simple steps) but before the core
# data processing.  The return value is a tuple of the new arguments that will
# be passed along.
#
# In this example, a call to `plot(myfunc, a, b, xlim=(-5,5))` is equivalent
# to the call `plot(lambdify(myfunc), a, b, xlim(-5,5))`
_apply_recipe(d::KW, f::F, args...; kw...) = (f.f, args...)

plot(F(sin), 0, 4π)


[Plots.jl] Initializing backend: pyplot
Out[8]:

In [9]:
# we can add another definition for vectors of our custom type
_apply_recipe(d::KW, v::AbstractVector{F}, args...; kw...) = (map(getf, v), args...)

v = [F(sin), F(cos)]
plot(v, 0, 4π)


Out[9]:

In [10]:
# 2D parametric
_apply_recipe(d::KW, f1::F, f2::F, args...; kw...) = (f1.f, f2.f, args...)
plot(F(sin), F(cos), 0, 4π)


Out[10]:

In [11]:
# 3D parametric
_apply_recipe(d::KW, f1::F, f2::F, f3::F, args...; kw...) = (f1.f, f2.f, f3.f, args...)
scatter3d(F(_->_+randn()), F(sin), F(cos), 0, 4π)


Out[11]:

In [15]:
# contours/surfaces
_apply_recipe(d::KW, v1, v2, f::F, args...; kw...) = (v1, v2, f.f)

x = linspace(-5, 5, 20)
y = x
f = F((x,y) -> x^2 + y^2)
contour(x, y, f)


Out[15]:

In [16]:
surface(x, y, f)


Out[16]:

In [ ]: