Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/stevengj/PyPlot.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengj committed Sep 9, 2013
2 parents dc7905b + ecc8a40 commit 7c59b3e
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 12 deletions.
69 changes: 58 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# The PyPlot module for Julia

This module provides a Julia interface to the
[matplotlib](http://matplotlib.org/) plotting library from Python, and
[Matplotlib](http://matplotlib.org/) plotting library from Python, and
specifically to the `matplotlib.pyplot` module.

PyPlot uses the Julia [PyCall](https://github.com/stevengj/PyCall.jl)
package to call matplotlib directly from Julia with little or no
package to call Matplotlib directly from Julia with little or no
overhead (arrays are passed without making a copy).

This package takes advantage of Julia's [multimedia
I/O](http://docs.julialang.org/en/latest/stdlib/base/#multimedia-i-o)
API to display plots in any Julia graphical backend, including as
inline graphics in [IJulia](https://github.com/JuliaLang/IJulia.jl).
Alternatively, you can use a Python-based graphical matplotlib
Alternatively, you can use a Python-based graphical Matplotlib
backend to support interactive plot zooming etcetera.

(This PyPlot package replaces an earlier package of the same name by
Expand All @@ -21,18 +21,18 @@ ZeroMQ socket with IPython.)

## Installation

You will need to have the Python [matplotlib](http://matplotlib.org/)
You will need to have the Python [Matplotlib](http://matplotlib.org/)
library installed on your machine in order to use PyPlot.

Once matplotlib is installed, then you can just use
Once Matplotlib is installed, then you can just use
`Pkg.add("PyPlot")` in Julia to install PyPlot and its dependencies.

**Note:** Julia version 0.2 (or a recent pre-release version thereof)
is required to use PyPlot.

## Basic usage

Once matplotlib and PyPlot is installed, and you are using a
Once Matplotlib and PyPlot is installed, and you are using a
graphics-capable Julia environment such as IJulia, you can simply type
`using PyPlot` and begin calling functions in the
[matplotlib.pyplot](http://matplotlib.org/api/pyplot_api.html) API.
Expand All @@ -50,16 +50,16 @@ exactly the same as in Python. (With minor translations, of course,
e.g. Julia uses `true` and `nothing` instead of Python's `True` and
`None`.)

The full matplotlib.pyplot API is far too extensive to describe here;
The full `matplotlib.pyplot` API is far too extensive to describe here;
see the [matplotlib.pyplot documentation for more
information](http://matplotlib.org/api/pyplot_api.html)

### Exported functions

Only the currently documented matplotlib.pyplot API is exported. To use
Only the currently documented `matplotlib.pyplot` API is exported. To use
other functions in the module, you can also call `matplotlib.pyplot.foo(...)`
as `plt.foo(...)`. For example, `plt.plot(x, y)` also works. (And
the raw `PyObject`s for the matplotlib and pyplot modules are accessible
the raw `PyObject`s for the `matplotlib` and `pyplot` modules are accessible
as `PyPlot.matplotlib` and `PyPlot.pltm`, respectively.)

You must also use `plt` to access some functions that conflict with
Expand All @@ -81,7 +81,7 @@ API](http://docs.julialang.org/en/latest/stdlib/base/#multimedia-i-o),
so you can use `display(fig)` to show a `fig::PyFigure` and
`writemime(io, mime, fig)` to write it to a given `mime` type string
(e.g. `"image/png"` or `"application/pdf"`) that is supported by the
matplotlib backend.
Matplotlib backend.

## Interactive versus Julia graphics

Expand All @@ -92,7 +92,7 @@ different backend, simply call `pushdisplay` with the desired
API](http://docs.julialang.org/en/latest/stdlib/base/#multimedia-i-o)
for more detail.

On the other hand, you may wish to use one of the Python matplotlib
On the other hand, you may wish to use one of the Python Matplotlib
backends to open an interactive window for each plot (for interactive
zooming, panning, etcetera). You can do this at any time by running:
```
Expand Down Expand Up @@ -154,6 +154,53 @@ Note that, given an SVG-supporting display environment like IJulia,
`ColorMap` and `Vector{ColorMap}` objects are displayed graphically;
try `get_cmaps()`!

## 3d Plotting

The PyPlot package also imports functions from Matplotlib's
[mplot3d](http://matplotlib.org/dev/mpl_toolkits/mplot3d/) toolkit.
Unlike Matplotlib, however, you can create 3d plots directly without
first creating an
[Axes3d](http://matplotlib.org/dev/mpl_toolkits/mplot3d/api.html#axes3d)
object, simply by calling one of: `bar3D, `contour3D`, `contourf3D`,
`plot3D`, `plot_surface`, `plot_trisurf`, `plot_wireframe`, or
`scatter3D` (as well as `text2D`, `text3D`), exactly like the
correspondingly named methods of
[Axes3d](http://matplotlib.org/dev/mpl_toolkits/mplot3d/api.html#axes3d).
We also export the Matlab-like synonyms `surf` for `plot_surface` (or
`plot_trisurf` for 1d-array arguments) and `mesh` for
`plot_wireframe`. For example, you can do:
```
surf(rand(30,40))
```
to plot a random 30×40 surface mesh.

You can also explicitly create a subplot with 3d axes via, for
example, `subplot(111, projection="3d")`, exactly as in Matplotlib.
The `Axes3d` constructor and the
[art3d](http://matplotlib.org/dev/mpl_toolkits/mplot3d/api.html#art3d)
module are also exported.

## LaTeX plot labels

Matplotlib allows you to [use LaTeX equations in plot
labels](http://matplotlib.org/users/mathtext.html), titles, and so on
simply by enclosing the equations in dollar signs (`$ ... $`) within
the string. However, typing LaTeX equations in Julia string literals
is awkward because escaping is necessary to prevent Julia from
interpreting the dollar signs and backslashes itself; for example, the
LaTeX equation `$\alpha + \beta$` would be the literal string
`"\$\\alpha + \\beta\$"` in Julia.

To simplify this, PyPlot provides a new `LaTeXString` type which can
be constructed via `L"...."` without escaping backslashes or dollar
signs. For example, one can simply write `L"$\alpha + \beta$"` for the
abovementioned equation, and thus you can do things like:
```
title(L"Plot of $\Gamma_3(x)$")
```
(As an added benefit, a `LaTeXString` is
automatically displayed as a rendered equation in IJulia.)

## Author

This module was written by [Steven G. Johnson](http://math.mit.edu/~stevenj/).
55 changes: 55 additions & 0 deletions src/PyPlot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ end

if isdefined(Main,:IJulia)
Main.IJulia.push_postexecute_hook(redisplay_figs)
Main.IJulia.push_posterror_hook(() -> begin
if drew_something[1] && isjulia_display[1]
pltm[:close]("all")
drew_something[1] = false # reset until next drawing command
end
end)
end

if isjulia_display[1] && backend != "Agg"
Expand Down Expand Up @@ -223,4 +229,53 @@ fill(x::AbstractArray,y::AbstractArray, args...; kws...) =

include("colormaps.jl")

###########################################################################
# Include mplot3d for 3d plotting.

export art3d, Axes3D, surf, mesh, bar3d, contour3D, contourf3D, plot3D, plot_surface, plot_trisurf, plot_wireframe, scatter3D, text2D, text3D

const mplot3d = pyimport("mpl_toolkits.mplot3d")
const axes3d = pyimport("mpl_toolkits.mplot3d.axes3d")

const art3d = pywrap(pyimport("mpl_toolkits.mplot3d.art3d"))
const Axes3D = axes3d[:Axes3D]

for f in (:bar3d, :contour3D, :contourf3D, :plot3D, :plot_surface,
:plot_trisurf, :plot_wireframe, :scatter3D, :text2D, :text3D)
fs = string(f)
@eval function $f(args...; kws...)
ax = gca(projection="3d")
pycall(ax[$fs], PyAny, args...; kws...)
end
end
const bar3D = bar3d # correct for annoying mplot3d inconsistency

# export Matlab-like names

function surf(Z::AbstractMatrix; kws...)
plot_surface([1:size(Z,1)]*ones(1,size(Z,2)),
ones(size(Z,1))*[1:size(Z,2)]', Z; kws...)
end

function surf(X, Y, Z::AbstractMatrix, args...; kws...)
plot_surface(X, Y, Z, args...; kws...)
end

function surf(X, Y, Z::AbstractVector, args...; kws...)
plot_trisurf(X, Y, Z, args...; kws...)
end

mesh(args...; kws...) = plot_wireframe(args...; kws...)

function mesh(Z::AbstractMatrix; kws...)
plot_wireframe([1:size(Z,1)]*ones(1,size(Z,2)),
ones(size(Z,1))*[1:size(Z,2)]', Z; kws...)
end

###########################################################################

include("latex.jl")

###########################################################################

end # module PyPlot
2 changes: 1 addition & 1 deletion src/colormaps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ get_cmaps() =
# display of ColorMaps as a horizontal color bar in SVG

const ScalarMappable = cm["ScalarMappable"]
const Normalize01 = colorsm[:Normalize](vmin=0,vmax=1)
const Normalize01 = pycall(colorsm["Normalize"],PyAny,vmin=0,vmax=1)

function writemime(io::IO, ::MIME"image/svg+xml",
cs::AbstractVector{ColorMap})
Expand Down
37 changes: 37 additions & 0 deletions src/latex.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Matplotlib supports LaTeX equations in plot labels etcetera, but
# these are annoying to type as string literals in Julia because of
# all the escaping required, e.g. "\$\\alpha + \\beta\$". To simplify
# this, we add a new string type with a macro constructor, so that
# one can simply do L"$\alpha + \beta$".

export LaTeXString, @L_str
import Base: writemime, show, write, endof, getindex, sizeof, search, rsearch, isvalid, next, length

immutable LaTeXString <: String
s::ByteString
end
macro L_str(s, flags...) LaTeXString(s) end

write(io::IO, s::LaTeXString) = write(io, s.s)
writemime(io::IO, ::MIME"application/x-latex", s::LaTeXString) = write(io, s)
writemime(io::IO, ::MIME"text/latex", s::LaTeXString) = write(io, s)

function show(io::IO, s::LaTeXString)
print(io, "L")
Base.print_quoted_literal(io, s.s)
end

bytestring(s::LaTeXString) = bytestring(s.s)
endof(s::LaTeXString) = endof(s.s)
next(s::LaTeXString, i::Int) = next(s.s, i)
length(s::LaTeXString) = length(s.s)
getindex(s::LaTeXString, i::Int) = getindex(s.s, i)
getindex(s::LaTeXString, i::Integer) = getindex(s.s, i)
getindex(s::LaTeXString, i::Real) = getindex(s.s, i)
getindex(s::LaTeXString, i::Range1{Int}) = getindex(s.s, i)
getindex{T<:Integer}(s::LaTeXString, i::Range1{T}) = getindex(s.s, i)
getindex(s::LaTeXString, i::AbstractVector) = getindex(s.s, i)
sizeof(s::LaTeXString) = sizeof(s.s)
search(s::LaTeXString, c::Char, i::Integer) = search(s.s, c, i)
rsearch(s::LaTeXString, c::Char, i::Integer) = rsearch(s.s, c, i)
isvalid(s::LaTeXString, i::Integer) = isvalid(s.s, i)

0 comments on commit 7c59b3e

Please sign in to comment.