From e0b2749188b55d59e28aa509814e98c26a82848a Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Fri, 8 Apr 2016 17:10:15 -0400 Subject: [PATCH] added support for shape linetype in pyplot --- src/backends/pyplot.jl | 40 ++++++++++++++++++++++++++++++++++++++- src/backends/supported.jl | 2 +- src/recipes.jl | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 598c2345..d13cd511 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -8,6 +8,7 @@ function _initialize_backend(::PyPlotBackend) const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors")) const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path")) const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d")) + const pypatches = PyPlot.pywrap(PyPlot.pyimport("matplotlib.patches")) # const pycolorbar = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colorbar")) end @@ -71,6 +72,31 @@ function getPyPlotMarker(marker::Shape) # marker.vertices end +const _path_MOVETO = UInt8(1) +const _path_LINETO = UInt8(2) +const _path_CLOSEPOLY = UInt8(79) + +# see http://matplotlib.org/users/path_tutorial.html +# and http://matplotlib.org/api/path_api.html#matplotlib.path.Path +function buildPyPlotPath(x, y) + n = length(x) + mat = zeros(n, 2) + codes = zeros(UInt8, n) + lastnan = true + for i=1:n + mat[i,1] = x[i] + mat[i,2] = y[i] + nan = !isfinite(x[i]) || !isfinite(y[i]) + codes[i] = if nan + _path_CLOSEPOLY + else + lastnan ? _path_MOVETO : _path_LINETO + end + lastnan = nan + end + pypath.pymember("Path")(mat, codes) +end + # get the marker shape function getPyPlotMarker(marker::Symbol) marker == :none && return " " @@ -177,6 +203,7 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol) :surface => :plot_surface, :wireframe => :plot_wireframe, :heatmap => :pcolor, + :shape => :add_patch, # :surface => pycolors.pymember("LinearSegmentedColormap")[:from_list] ) return ax[get(fmap, linetype, :plot)] @@ -376,6 +403,12 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...) elseif lt == :heatmap extra_kwargs[:cmap] = getPyPlotColorMap(d[:fillcolor], d[:fillalpha]) + elseif lt == :shape + extra_kwargs[:edgecolor] = getPyPlotColor(d[:markerstrokecolor], d[:markerstrokealpha]) + extra_kwargs[:facecolor] = getPyPlotColor(d[:markercolor], d[:markeralpha]) + extra_kwargs[:linewidth] = d[:markerstrokewidth] + extra_kwargs[:fill] = true + else extra_kwargs[:linestyle] = getPyPlotLineStyle(lt, d[:linestyle]) @@ -425,7 +458,7 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...) # set these for all types if !(lt in (:contour,:surface,:wireframe,:heatmap)) - if !(lt in (:scatter, :scatter3d)) + if !(lt in (:scatter, :scatter3d, :shape)) extra_kwargs[:color] = color extra_kwargs[:linewidth] = d[:linewidth] end @@ -476,6 +509,11 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...) x, y, z = d[:x], d[:y], d[:z].surf' plotfunc(heatmap_edges(x), heatmap_edges(y), z; extra_kwargs...) + elseif lt == :shape + path = buildPyPlotPath(d[:x], d[:y]) + patches = pypatches.pymember("PathPatch")(path; extra_kwargs...) + plotfunc(patches) + else # plot plotfunc(d[:x], d[:y]; extra_kwargs...)[1] end diff --git a/src/backends/supported.jl b/src/backends/supported.jl index 8750a569..e117b58a 100644 --- a/src/backends/supported.jl +++ b/src/backends/supported.jl @@ -176,7 +176,7 @@ supportedArgs(::PyPlotBackend) = [ :orientation, ] supportedAxes(::PyPlotBackend) = _allAxes -supportedTypes(::PyPlotBackend) = [:none, :line, :path, :steppre, :steppost, #:sticks, +supportedTypes(::PyPlotBackend) = [:none, :line, :path, :steppre, :steppost, :shape, :scatter, :hist2d, :hexbin, :hist, :density, :bar, :box, :violin, :quiver, :hline, :vline, :contour, :path3d, :scatter3d, :surface, :wireframe, :heatmap] supportedStyles(::PyPlotBackend) = [:auto, :solid, :dash, :dot, :dashdot] diff --git a/src/recipes.jl b/src/recipes.jl index 954db30b..f8b70830 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -302,7 +302,7 @@ function apply_series_recipe(d::KW, ::Type{Val{:quiver}}) nanappend!(pts, P2[p, ppv-U1, ppv-U1+U2, ppv, ppv-U1-U2, ppv-U1]) end - d[:x], d[:y] = Plots.unzip(pts) + d[:x], d[:y] = Plots.unzip(pts[2:end]) KW[d] end