From ebf490838c2c565d6f9d489d05c07ab7fec7e580 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Mon, 25 Apr 2016 15:01:24 -0400 Subject: [PATCH] pyplot surface, wireframe, heatmap; sorting fixes; default linewidth is :auto --- src/args.jl | 17 +++++++++------ src/backends/pyplot.jl | 48 ++++++++++++++++++++++++++++++------------ src/colors.jl | 4 ++++ src/plot.jl | 1 + src/series_args.jl | 26 ++++++++++++++++------- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/args.jl b/src/args.jl index 78f5e836..f6278ea4 100644 --- a/src/args.jl +++ b/src/args.jl @@ -117,7 +117,7 @@ _seriesDefaults[:seriescolor] = :auto _seriesDefaults[:seriesalpha] = nothing _seriesDefaults[:linetype] = :path _seriesDefaults[:linestyle] = :solid -_seriesDefaults[:linewidth] = 1 +_seriesDefaults[:linewidth] = :auto _seriesDefaults[:linecolor] = :match _seriesDefaults[:linealpha] = nothing _seriesDefaults[:fillrange] = nothing # ribbons, areas, etc @@ -266,13 +266,13 @@ add_aliases(:foreground_color, :fg, :fgcolor, :fg_color, :foreground, add_aliases(:foreground_color_legend, :fg_legend, :fglegend, :fgcolor_legend, :fg_color_legend, :foreground_legend, :foreground_colour_legend, :fgcolour_legend, :fg_colour_legend) add_aliases(:foreground_color_grid, :fg_grid, :fggrid, :fgcolor_grid, :fg_color_grid, :foreground_grid, - :foreground_colour_grid, :fgcolour_grid, :fg_colour_grid) + :foreground_colour_grid, :fgcolour_grid, :fg_colour_grid, :gridcolor) add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis, - :foreground_colour_axis, :fgcolour_axis, :fg_colour_axis) + :foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor) add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text, - :foreground_colour_text, :fgcolour_text, :fg_colour_text) + :foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor) add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border, - :foreground_colour_border, :fgcolour_border, :fg_colour_border) + :foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor, :border) # alphas add_aliases(:seriesalpha, :alpha, :α, :opacity) @@ -608,10 +608,13 @@ function preprocessArgs!(d::KW) end # handle line args - for arg in wraptuple(get(d, :line, ())) + for arg in wraptuple(pop!(d, :line, ())) processLineArg(d, arg) end - delete!(d, :line) + # delete!(d, :line) + if get(d, :linewidth, :auto) == :auto + d[:linewidth] = (get(d, :linetype, :path) in (:surface,:heatmap) ? 0 : 1) + end # handle marker args... default to ellipse if shape not set anymarker = false diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ca7cef72..32d27a87 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -367,10 +367,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) # TODO # :density => :hist, - # :contour => :contour, - # :surface => :plot_surface, - # :wireframe => :plot_wireframe, - # :heatmap => :pcolor, # :shape => :add_patch, @@ -417,7 +413,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) end end - # bars if lt in (:bar, :sticks) extrakw[isvertical(d) ? :width : :height] = (lt == :sticks ? 0.1 : 0.9) handle = ax[isvertical(d) ? :bar : :barh](x, y; @@ -432,7 +427,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) push!(handles, handle) end - # histograms if lt == :hist handle = ax[:hist](y; label = d[:label], @@ -449,7 +443,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) push!(handles, handle) end - # 2d histograms if lt == :hist2d handle = ax[:hist2d](x, y; label = d[:label], @@ -462,7 +455,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) push!(handles, handle) end - # hexbins if lt == :hexbin handle = ax[:hexbin](x, y; label = d[:label], @@ -476,7 +468,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) needs_colorbar = true end - # horizontal and vertical lines if lt in (:hline,:vline) for yi in d[:y] func = ax[lt == :hline ? :axhline : :axvline] @@ -489,7 +480,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) end end - # contours if lt == :contour z = z.surf' needs_colorbar = true @@ -526,6 +516,40 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW) push!(handles, handle) end + if lt in (:surface, :wireframe) + x, y, z = map(Array, (x,y,z)) + if !ismatrix(x) || !ismatrix(y) + x = repmat(x', length(y), 1) + y = repmat(y, 1, length(d[:x])) + z = z' + end + if lt == :surface + extrakw[:cmap] = pyfillcolormap(d) + needs_colorbar = true + end + handle = ax[lt == :surface ? :plot_surface : :plot_wireframe](x, y, z; + label = d[:label], + zorder = plt.n, + rstride = 1, + cstride = 1, + linewidth = d[:linewidth], + edgecolor = pylinecolor(d), + extrakw... + ) + push!(handles, handle) + end + + if lt == :heatmap + x, y, z = heatmap_edges(x), heatmap_edges(y), z.surf' + handle = ax[:pcolormesh](x, y, z; + label = d[:label], + zorder = plt.n, + cmap = pyfillcolormap(d), + edgecolors = (d[:linewidth] > 0 ? pylinecolor(d) : "face") + ) + push!(handles, handle) + end + d[:serieshandle] = handles # smoothing @@ -1098,8 +1122,6 @@ function finalizePlot(plt::Plot{PyPlotBackend}) ax = getLeftAxis(plt) addPyPlotLegend(plt, ax) updateAxisColors(ax, plt.plotargs) - # updateAxisColors(ax, getPyPlotColor(plt.plotargs[:foreground_color_axis]), - # getPyPlotColor(plt.plotargs[:foreground_color_text])) PyPlot.draw() end @@ -1109,8 +1131,6 @@ function finalizePlot(subplt::Subplot{PyPlotBackend}) ax = getLeftAxis(plt) addPyPlotLegend(plt, ax) updateAxisColors(ax, plt.plotargs) - # updateAxisColors(ax, getPyPlotColor(plt.plotargs[:foreground_color_axis]), - # getPyPlotColor(plt.plotargs[:foreground_color_text])) end # fig[:tight_layout]() PyPlot.draw() diff --git a/src/colors.jl b/src/colors.jl index 13dff212..4acceafb 100644 --- a/src/colors.jl +++ b/src/colors.jl @@ -392,6 +392,8 @@ function handlePlotColors(::AbstractBackend, d::KW) bgsym = symbol("background_color_" * bgtype) if d[bgsym] == :match d[bgsym] = d[:background_color] + elseif d[bgsym] == nothing + d[bgsym] = colorscheme(RGBA(0,0,0,0)) end end @@ -400,6 +402,8 @@ function handlePlotColors(::AbstractBackend, d::KW) fgsym = symbol("foreground_color_" * fgtype) if d[fgsym] == :match d[fgsym] = d[:foreground_color] + elseif d[fgsym] == nothing + d[fgsym] = colorscheme(RGBA(0,0,0,0)) end end diff --git a/src/plot.jl b/src/plot.jl index 7594533a..e5edccd4 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -99,6 +99,7 @@ function plot!(plt::Plot, args...; kw...) # add title, axis labels, ticks, etc if !haskey(d, :subplot) merge!(plt.plotargs, d) + handlePlotColors(plt.backend, plt.plotargs) dumpdict(plt.plotargs, "Updating plot items") _update_plot(plt, plt.plotargs) end diff --git a/src/series_args.jl b/src/series_args.jl index 1f9fd871..8db6e392 100644 --- a/src/series_args.jl +++ b/src/series_args.jl @@ -293,21 +293,31 @@ function process_inputs(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zvec::AVec) end # surface-like... function -function process_inputs(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zf::Function) - x, y = sort(x), sort(y) +function process_inputs{TX,TY}(plt::AbstractPlot, d::KW, x::AVec{TX}, y::AVec{TY}, zf::Function) + x = TX <: Number ? sort(x) : x + y = TY <: Number ? sort(y) : y + # x, y = sort(x), sort(y) d[:z] = Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported d[:x], d[:y] = x, y end # surface-like... matrix grid -function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zmat::AMat{T}) +function process_inputs{TX,TY,TZ<:Number}(plt::AbstractPlot, d::KW, x::AVec{TX}, y::AVec{TY}, zmat::AMat{TZ}) @assert size(zmat) == (length(x), length(y)) - if !issorted(x) || !issorted(y) - x_idx = sortperm(x) - y_idx = sortperm(y) - x, y = x[x_idx], y[y_idx] - zmat = zmat[x_idx, y_idx] + if TX <: Number && !issorted(x) + idx = sortperm(x) + x, zmat = x[idx], zmat[idx, :] end + if TY <: Number && !issorted(y) + idx = sortperm(y) + y, zmat = y[idx], zmat[:, idx] + end + # + # !issorted(y) + # y_idx = sortperm(y) + # x, y = x[x_idx], y[y_idx] + # zmat = zmat[x_idx, y_idx] + # end d[:x], d[:y], d[:z] = x, y, Surface{Matrix{Float64}}(zmat) if !like_surface(get(d, :linetype, :none)) d[:linetype] = :contour