The following reproduces the surface plot example from mplot3d:
fig = figure()
X = linspace(-5, 5, 100)'
Y = linspace(-5, 5, 100)
R = sqrt(X.^2 .+ Y.^2)
Z = sin(R)
surf = plot_surface(X, Y, Z, rstride=1, cstride=1, linewidth=0, antialiased=false, cmap="coolwarm")
zlim(-1.01,1.01)
ax = gca()
ax[:zaxis][:set_major_locator](matplotlib[:ticker][:LinearLocator](10))
ax[:zaxis][:set_major_formatter](matplotlib[:ticker][:FormatStrFormatter]("%.02f"))
fig[:colorbar](surf, shrink=0.5, aspect=5)
("surf" is a Matlab-like synonym for "plot_surface" in PyPlot.)
You don't need meshgrid because you can
use broadcasting operations (.+) instead to combine a row vector (X: notice the ' to transpose the linspace) and a column vector (Y).
Unlike in mplot3d, you don't need to create the axis with gca(projection="3d"), because the 3d plotting functions like plot_surface do this for you in PyPlot.
As explained in the PyCall documentation, instead of foo.bar() in Python you do foo[:bar]() in Julia. This is because Julia doesn't yet
allow . to be overloaded.