aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-02-23 13:14:13 -0800
committerbnewbold <bnewbold@robocracy.org>2016-02-23 13:14:17 -0800
commitfa8f048e78bb9965902371f937d761267bd6b63b (patch)
treeb59fd1203d5bd6d90eefa593bd210b26846fc58e
parentba0bb2fc756deaa8f02cc58148fc4ef9095e85ff (diff)
downloadPyX.jl-fa8f048e78bb9965902371f937d761267bd6b63b.tar.gz
PyX.jl-fa8f048e78bb9965902371f937d761267bd6b63b.zip
huge rework adding MIME output support, PyxCanvas, wrapper, more
Apes PyPlot to map a new Julia type (PyxCanvas) to the PyX python "canvas" class, and defines many methods on this new type, including MIME output. Also addes ghostscript piping stuff, and corrects Python3 (SVG) support. This now at least sort-of works with Jupyter. Probably needs a refactor/cleanup, definately needs mime-specific tests, and the Graph object should also be wrapped (PyxGraph).
-rw-r--r--README.md2
-rw-r--r--src/PyX.jl114
2 files changed, 77 insertions, 39 deletions
diff --git a/README.md b/README.md
index 031f8cc..8cd198f 100644
--- a/README.md
+++ b/README.md
@@ -40,3 +40,5 @@ following functions have "pyx_" preprended to the function name:
Also check the TODO file.
+For pipeGS (ghostscript file conversion) output, see:
+http://www.ghostscript.com/doc/current/Devices.htm
diff --git a/src/PyX.jl b/src/PyX.jl
index 9210f5e..ce1acd0 100644
--- a/src/PyX.jl
+++ b/src/PyX.jl
@@ -1,9 +1,51 @@
module PyX
+####### Required and over-written
using PyCall
-using LaTeXStrings
+import PyCall: pycall
+import Base: convert, ==, isequal, hash, writemime, getindex, setindex!, haskey, keys, show, mimewritable
+
+# LaTeXStrings is strongly recommended but not required
+
+####### Types
+export PyxCanvas
+# Wrapper around PyX PyxCanvas, supporting graphics I/O and pretty display
+# Based on PyPlot's Figure type
+type PyxCanvas
+ o::PyObject
+end
+
+PyObject(f::PyxCanvas) = f.o
+convert(::Type{PyxCanvas}, o::PyObject) = PyxCanvas(o)
+==(f::PyxCanvas, g::PyxCanvas) = f.o == g.o
+==(f::PyxCanvas, g::PyObject) = f.o == g
+==(f::PyObject, g::PyxCanvas) = f == g.o
+hash(f::PyxCanvas) = hash(f.o)
+pycall(f::PyxCanvas, args...; kws...) = pycall(f.o, args...; kws...)
+Base.call(f::PyxCanvas, args...; kws...) = pycall(f.o, PyAny, args...; kws...)
+Base.Docs.doc(f::PyxCanvas) = Base.Docs.doc(f.o)
+getindex(f::PyxCanvas, x) = getindex(f.o, x)
+setindex!(f::PyxCanvas, v, x) = setindex!(f.o, v, x)
+haskey(f::PyxCanvas, x) = haskey(f.o, x)
+keys(f::PyxCanvas) = keys(f.o)
+
+mimewritable(::MIME"application/eps", c::PyxCanvas) = !isempty(c.o[:items])
+mimewritable(::MIME"image/eps", c::PyxCanvas) = !isempty(c.o[:items])
+mimewritable(::MIME"application/pdf", c::PyxCanvas) = !isempty(c.o[:items])
+mimewritable(::MIME"application/postscript", c::PyxCanvas) = !isempty(c.o[:items])
+mimewritable(::MIME"image/png", c::PyxCanvas) = !isempty(c.o[:items])
+mimewritable(::MIME"image/jpeg", c::PyxCanvas) = !isempty(c.o[:items])
+
+writemime(io::IO, ::MIME"application/pdf", c::PyxCanvas) = writePDFfile(c, io)
+writemime(io::IO, ::MIME"application/eps", c::PyxCanvas) = writeEPSfile(c, io)
+writemime(io::IO, ::MIME"image/eps", c::PyxCanvas) = writeEPSfile(c, io)
+writemime(io::IO, ::MIME"application/postscript", c::PyxCanvas) = writePSfile(c, io)
+writemime(io::IO, ::MIME"image/png", c::PyxCanvas) = writeGSfile(c, io, "png16m")
+writemime(io::IO, ::MIME"image/jpeg", c::PyxCanvas) = writeGSfile(c, io, "jpeg")
+
+####### Exports
export canvas, path, deco, deco_stroked, deco_filled
export connector, text, text_halign, text_valign, box
export style, style_linewidth, style_linestyle, style_linejoin, style_linecap
@@ -12,10 +54,11 @@ export graph, graph_axis, graph_axis_painter, graph_data, graph_style, graph_sty
export graph_graphxyz, graph_data_function
export epsfile, deformer, trafo, attr, metapost_path
export plot, stroke
-export writeEPSfile, writePDFfile
+export writeEPSfile, writePDFfile, writeGSfile, pipeGS
export pyx_fill, pyx_append, pyx_insert, pyx_text
# See also Python3 section at end
+####### Create virtual (pywrap) Julia modules for PyX python sub-modules
canvas = pywrap(pyimport("pyx.canvas"))
path = pywrap(pyimport("pyx.path"))
deco = pywrap(pyimport("pyx.deco"))
@@ -51,50 +94,43 @@ trafo = pywrap(pyimport("pyx.trafo"))
attr = pywrap(pyimport("pyx.attr"))
metapost_path = pywrap(pyimport("pyx.metapost.path"))
-function plot(g::PyObject, args...; kwargs...)
- # g should be Graph object
- return g[:plot](args...; kwargs...)
-end
-
-function stroke(c::PyObject, args...; kwargs...)
- # c should be Canvas object
- return c[:stroke](args...; kwargs...)
-end
-
-function pyx_fill(c::PyObject, args...; kwargs...)
- # c should be Canvas object
- return c[:fill](args...; kwargs...)
-end
-
-function pyx_text(c::PyObject, args...; kwargs...)
- # c should be Canvas object
- return c[:text](args...; kwargs...)
-end
+####### Wrapper Functions
+plot(g::PyObject, a...; k...) = g[:plot](a...; k...)
+plot(g::PyxCanvas, a...; k...) = g[:plot](a...; k...)
+stroke(c::PyxCanvas, a...; k...) = c[:stroke](a...; k...)
+pyx_fill(c::PyxCanvas, a...; k...) = c[:fill](a...; k...)
+pyx_text(c::PyxCanvas, a...; k...) = c[:text](a...; k...)
+pyx_insert(c::PyxCanvas, a...; k...) = c[:insert](a...; k...)
-function pyx_append(p::PyObject, args...; kwargs...)
- # p should be Path object
- return p[:append](args...; kwargs...)
-end
+# p should be Path object
+pyx_append(p::PyObject, a...; k...) = p[:append](a...; k...)
-function pyx_insert(c::PyObject, args...; kwargs...)
- # c should be Canvas object
- return c[:insert](args...; kwargs...)
-end
+writeEPSfile(g::PyObject, a...; k...) = g[:writeEPSfile](a...; k...)
+writeEPSfile(c::PyxCanvas, a...; k...) = c[:writeEPSfile](a...; k...)
+writePDFfile(g::PyObject, a...; k...) = g[:writePDFfile](a...; k...)
+writePDFfile(c::PyxCanvas, a...; k...) = c[:writePDFfile](a...; k...)
+writeGSfile(g::PyObject, a...; k...) = g[:writeGSfile](a...; k...)
+writeGSfile(c::PyxCanvas, a...; k...) = c[:writeGSfile](a...; k...)
-function writeEPSfile(g::PyObject, args...; kwargs...)
- return g[:writeEPSfile](args...; kwargs...)
+# Some newer features only in recent (Python3) versions of PyX
+if PyCall.pyversion > v"3"
+ export writeSVGfile
+ writeSVGfile(g::PyObject, a...; k...) = g[:writeSVGfile](a...; k...)
+ writeSVGfile(c::PyxCanvas, a...; k...) = c[:writeSVGfile](a...; k...)
+ mimewritable(::MIME"image/svg+xml", c::PyxCanvas) = !isempty(c.o[:items])
+ writemime(io::IO, ::MIME"image/svg+xml", c::PyxCanvas) = writeSVGfile(c, io)
end
-function writePDFfile(g::PyObject, args...; kwargs...)
- return g[:writePDFfile](args...; kwargs...)
+##### Actual Meaty Functions
+function __init__()
+ pytype_mapping(canvas.canvas, PyxCanvas)
end
-# Some newer features only in recent (Python3) versions of PyX
-if PyCall.pyversion > v"3"
- export writeSVGfile
- function writeSVGfile(g::PyObject, args...; kwargs...)
- return g[:writeSVGfile](args...; kwargs...)
- end
+function pipeGS(g::PyxCanvas, args...; device="png16m", kwargs...)
+ f = g[:pipeGS](args...; device=device, kwargs...)
+ d = f[:read]()
+ f[:close]()
+ return d
end
end # module PyX