support for contours in gadfly/immerse/pyplot
This commit is contained in:
parent
614c5f694b
commit
9ea0585d71
@ -4,7 +4,6 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
julia:
|
||||
- 0.3
|
||||
- 0.4
|
||||
#- nightly
|
||||
notifications:
|
||||
@ -17,5 +16,5 @@ script:
|
||||
- julia -e 'Pkg.clone("Cairo"); Pkg.build("Cairo")'
|
||||
- julia -e 'ENV["PYTHON"] = ""; Pkg.clone("PyPlot"); Pkg.build("PyPlot")'
|
||||
- julia -e 'Pkg.clone(pwd()); Pkg.build("Plots")'
|
||||
- julia -e 'Pkg.test("Plots"; coverage=true)'
|
||||
- julia -e 'Pkg.test("Plots"; coverage=false)'
|
||||
# - julia -e 'cd(Pkg.dir("Plots")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder()); Codecov.submit(process_folder())'
|
||||
|
||||
@ -8,7 +8,7 @@ const _allAxes = [:auto, :left, :right]
|
||||
)
|
||||
|
||||
const _allTypes = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||
:heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc]
|
||||
:heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc, :contour]
|
||||
@compat const _typeAliases = Dict(
|
||||
:n => :none,
|
||||
:no => :none,
|
||||
@ -26,6 +26,7 @@ const _allTypes = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||
:stems => :sticks,
|
||||
:dots => :scatter,
|
||||
:histogram => :hist,
|
||||
:contours => :contours,
|
||||
)
|
||||
|
||||
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
@ -130,6 +131,8 @@ _seriesDefaults[:z] = nothing # depth for contour, color sca
|
||||
# _seriesDefaults[:args] = [] # additional args to pass to the backend
|
||||
# _seriesDefaults[:kwargs] = [] # additional keyword args to pass to the backend
|
||||
# # note: can be Vector{Dict} or Vector{Tuple}
|
||||
_seriesDefaults[:surface] = nothing
|
||||
_seriesDefaults[:nlevels] = 15
|
||||
|
||||
|
||||
const _plotDefaults = Dict{Symbol, Any}()
|
||||
|
||||
@ -39,6 +39,8 @@ function getLineGeom(d::Dict)
|
||||
Gadfly.Geom.hline(color = getColor(d[:color]), size = d[:linewidth] * Gadfly.px)
|
||||
elseif lt == :vline
|
||||
Gadfly.Geom.vline(color = getColor(d[:color]), size = d[:linewidth] * Gadfly.px)
|
||||
elseif lt == :contour
|
||||
Gadfly.Geom.contour(levels = d[:nlevels])
|
||||
else
|
||||
nothing
|
||||
end
|
||||
@ -94,6 +96,8 @@ function addGadflyLine!(plt::Plot, d::Dict, geoms...)
|
||||
w = 0.01 * mean(diff(d[:x]))
|
||||
kwargs[:xmin] = d[:x] - w
|
||||
kwargs[:xmax] = d[:x] + w
|
||||
elseif lt == :contour
|
||||
kwargs[:z] = d[:surface]
|
||||
end
|
||||
|
||||
# add the layer
|
||||
@ -224,7 +228,7 @@ function addGadflySeries!(plt::Plot, d::Dict)
|
||||
prepend!(layers, addGadflyMarker!(plt, d, plt.initargs, smooth...))
|
||||
end
|
||||
|
||||
lt in (:hist, :heatmap, :hexbin) || addToGadflyLegend(plt, d)
|
||||
lt in (:hist, :heatmap, :hexbin, :contour) || addToGadflyLegend(plt, d)
|
||||
|
||||
# now save the layers that apply to this series
|
||||
d[:gadflylayers] = layers
|
||||
|
||||
@ -8,10 +8,10 @@ getPyPlotColor(c::Colorant) = map(f->float(f(c)), (red, green, blue, alpha))
|
||||
getPyPlotColor(scheme::ColorScheme) = getPyPlotColor(getColor(scheme))
|
||||
getPyPlotColor(c) = getPyPlotColor(convertColor(c))
|
||||
|
||||
# getPyPlotColorMap(c::ColorGradient) = PyPlot.matplotlib[:colors][:ListedColormap](map(getPyPlotColor, getColorVector(c)))
|
||||
function getPyPlotColorMap(c::ColorGradient)
|
||||
pycolors.pymember("LinearSegmentedColormap")[:from_list]("tmp", map(getPyPlotColor, getColorVector(c)))
|
||||
end
|
||||
getPyPlotColorMap(c) = getPyPlotColorMap(ColorGradient(:redsblues))
|
||||
|
||||
# get the style (solid, dashed, etc)
|
||||
function getPyPlotLineStyle(linetype::Symbol, linestyle::Symbol)
|
||||
@ -107,7 +107,8 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
|
||||
:bar => :bar,
|
||||
:heatmap => :hexbin,
|
||||
:hexbin => :hexbin,
|
||||
:scatter => :scatter
|
||||
:scatter => :scatter,
|
||||
:contour => :contour,
|
||||
)
|
||||
return ax[get(fmap, linetype, :plot)]
|
||||
end
|
||||
@ -125,6 +126,7 @@ function updateAxisColors(ax, fgcolor)
|
||||
ax[:title][:set_color](fgcolor)
|
||||
end
|
||||
|
||||
|
||||
nop() = nothing
|
||||
|
||||
|
||||
@ -195,7 +197,7 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
end
|
||||
|
||||
lt = d[:linetype]
|
||||
extraargs = Dict()
|
||||
extra_kwargs = Dict()
|
||||
|
||||
plotfunc = getPyPlotFunction(plt, d[:axis], lt)
|
||||
|
||||
@ -203,63 +205,71 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
if lt in (:hist, :sticks, :bar)
|
||||
|
||||
# NOTE: this is unsupported because it does the wrong thing... it shifts the whole axis
|
||||
# extraargs[:bottom] = d[:fill]
|
||||
# extra_kwargs[:bottom] = d[:fill]
|
||||
|
||||
if lt == :hist
|
||||
extraargs[:bins] = d[:nbins]
|
||||
extra_kwargs[:bins] = d[:nbins]
|
||||
else
|
||||
extraargs[:linewidth] = (lt == :sticks ? 0.1 : 0.9)
|
||||
extra_kwargs[:linewidth] = (lt == :sticks ? 0.1 : 0.9)
|
||||
end
|
||||
|
||||
elseif lt in (:heatmap, :hexbin)
|
||||
extra_kwargs[:gridsize] = d[:nbins]
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(d[:color])
|
||||
|
||||
extraargs[:gridsize] = d[:nbins]
|
||||
c = d[:color]
|
||||
if !isa(c, ColorGradient)
|
||||
c = ColorGradient(:redsblues)
|
||||
end
|
||||
# c = ColorGradient(d[:color])
|
||||
extraargs[:cmap] = getPyPlotColorMap(c)
|
||||
elseif lt == :contour
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(d[:color])
|
||||
extra_kwargs[:linewidths] = d[:linewidth]
|
||||
extra_kwargs[:linestyles] = getPyPlotLineStyle(lt, d[:linestyle])
|
||||
# TODO: will need to call contourf to fill in the contours
|
||||
|
||||
else
|
||||
|
||||
extraargs[:linestyle] = getPyPlotLineStyle(lt, d[:linestyle])
|
||||
extraargs[:marker] = getPyPlotMarker(d[:markershape])
|
||||
extra_kwargs[:linestyle] = getPyPlotLineStyle(lt, d[:linestyle])
|
||||
extra_kwargs[:marker] = getPyPlotMarker(d[:markershape])
|
||||
|
||||
if lt == :scatter
|
||||
extraargs[:s] = d[:markersize]^2
|
||||
extra_kwargs[:s] = d[:markersize]^2
|
||||
c = d[:markercolor]
|
||||
if isa(c, ColorGradient) && d[:z] != nothing
|
||||
extraargs[:c] = convert(Vector{Float64}, d[:z])
|
||||
extraargs[:cmap] = getPyPlotColorMap(c)
|
||||
extra_kwargs[:c] = convert(Vector{Float64}, d[:z])
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(c)
|
||||
else
|
||||
extraargs[:c] = getPyPlotColor(c)
|
||||
extra_kwargs[:c] = getPyPlotColor(c)
|
||||
end
|
||||
else
|
||||
extraargs[:markersize] = d[:markersize]
|
||||
extraargs[:markerfacecolor] = getPyPlotColor(d[:markercolor])
|
||||
extraargs[:markeredgecolor] = getPyPlotColor(plt.initargs[:foreground_color])
|
||||
extraargs[:markeredgewidth] = d[:linewidth]
|
||||
extraargs[:drawstyle] = getPyPlotDrawStyle(lt)
|
||||
extra_kwargs[:markersize] = d[:markersize]
|
||||
extra_kwargs[:markerfacecolor] = getPyPlotColor(d[:markercolor])
|
||||
extra_kwargs[:markeredgecolor] = getPyPlotColor(plt.initargs[:foreground_color])
|
||||
extra_kwargs[:markeredgewidth] = d[:linewidth]
|
||||
extra_kwargs[:drawstyle] = getPyPlotDrawStyle(lt)
|
||||
end
|
||||
end
|
||||
|
||||
# set these for all types
|
||||
extraargs[:color] = getPyPlotColor(d[:color])
|
||||
extraargs[:linewidth] = d[:linewidth]
|
||||
extraargs[:label] = d[:label]
|
||||
if lt != :contour
|
||||
extra_kwargs[:color] = getPyPlotColor(d[:color])
|
||||
extra_kwargs[:linewidth] = d[:linewidth]
|
||||
extra_kwargs[:label] = d[:label]
|
||||
end
|
||||
|
||||
# do the plot
|
||||
d[:serieshandle] = if lt == :hist
|
||||
plotfunc(d[:y]; extraargs...)[1]
|
||||
plotfunc(d[:y]; extra_kwargs...)[1]
|
||||
elseif lt == :contour
|
||||
handle = plotfunc(d[:x], d[:y], d[:surface], d[:nlevels]; extra_kwargs...)
|
||||
if d[:fillrange] != nothing
|
||||
handle = ax[:contourf](d[:x], d[:y], d[:surface], d[:nlevels]; cmap = getPyPlotColorMap(d[:fillcolor]))
|
||||
end
|
||||
handle
|
||||
elseif lt in (:scatter, :heatmap, :hexbin)
|
||||
plotfunc(d[:x], d[:y]; extraargs...)
|
||||
plotfunc(d[:x], d[:y]; extra_kwargs...)
|
||||
else
|
||||
plotfunc(d[:x], d[:y]; extraargs...)[1]
|
||||
plotfunc(d[:x], d[:y]; extra_kwargs...)[1]
|
||||
end
|
||||
|
||||
# add the colorbar legend
|
||||
if plt.initargs[:legend] && haskey(extraargs, :cmap)
|
||||
if plt.initargs[:legend] && haskey(extra_kwargs, :cmap)
|
||||
PyPlot.colorbar(d[:serieshandle])
|
||||
end
|
||||
|
||||
@ -267,7 +277,7 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
ax[:set_axis_bgcolor](getPyPlotColor(plt.initargs[:background_color]))
|
||||
|
||||
fillrange = d[:fillrange]
|
||||
if fillrange != nothing
|
||||
if fillrange != nothing && lt != :contour
|
||||
fillcolor = getPyPlotColor(d[:fillcolor])
|
||||
if typeof(fillrange) <: @compat(Union{Real, AVec})
|
||||
ax[:fill_between](d[:x], fillrange, d[:y], facecolor = fillcolor)
|
||||
@ -494,7 +504,7 @@ end
|
||||
function addPyPlotLegend(plt::Plot, ax)
|
||||
if plt.initargs[:legend]
|
||||
# gotta do this to ensure both axes are included
|
||||
args = filter(x -> !(x[:linetype] in (:hist,:hexbin,:heatmap,:hline,:vline)), plt.seriesargs)
|
||||
args = filter(x -> !(x[:linetype] in (:hist,:hexbin,:heatmap,:hline,:vline,:contour)), plt.seriesargs)
|
||||
if length(args) > 0
|
||||
ax[:legend]([d[:serieshandle] for d in args],
|
||||
[d[:label] for d in args],
|
||||
|
||||
@ -49,9 +49,11 @@ supportedArgs(::GadflyPackage) = [
|
||||
:guidefont,
|
||||
:legendfont,
|
||||
:grid,
|
||||
:surface,
|
||||
:nlevels,
|
||||
]
|
||||
supportedAxes(::GadflyPackage) = [:auto, :left]
|
||||
supportedTypes(::GadflyPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc]
|
||||
supportedTypes(::GadflyPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :contour]
|
||||
supportedStyles(::GadflyPackage) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
supportedMarkers(::GadflyPackage) = vcat(_allMarkers, Shape)
|
||||
supportedScales(::GadflyPackage) = [:identity, :log, :log2, :log10, :asinh, :sqrt]
|
||||
@ -122,9 +124,11 @@ supportedArgs(::PyPlotPackage) = [
|
||||
:guidefont,
|
||||
:legendfont,
|
||||
# :grid,
|
||||
:surface,
|
||||
:nlevels,
|
||||
]
|
||||
supportedAxes(::PyPlotPackage) = _allAxes
|
||||
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
|
||||
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :contour]
|
||||
supportedStyles(::PyPlotPackage) = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
# supportedMarkers(::PyPlotPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :hexagon]
|
||||
supportedMarkers(::PyPlotPackage) = vcat(_allMarkers, Shape)
|
||||
|
||||
28
src/plot.jl
28
src/plot.jl
@ -321,20 +321,38 @@ function createKWargsList(plt::PlottingObject, y; kw...)
|
||||
createKWargsList(plt, nothing, y; kw...)
|
||||
end
|
||||
|
||||
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, z::AVec; kw...)
|
||||
# contours or surfaces... irregular data
|
||||
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, zvec::AVec; kw...)
|
||||
error("TODO: contours or surfaces... irregular data")
|
||||
end
|
||||
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, z::Function; kw...)
|
||||
error("TODO: contours or surfaces... function grid")
|
||||
|
||||
# contours or surfaces... function grid
|
||||
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, zf::Function; kw...)
|
||||
# only allow sorted x/y for now
|
||||
# TODO: auto sort x/y/z properly
|
||||
@assert x == sort(x)
|
||||
@assert y == sort(y)
|
||||
surface = Float64[zf(xi, yi) for xi in x, yi in y]
|
||||
createKWargsList(plt, x, y, surface; kw...) # passes it to the zmat version
|
||||
end
|
||||
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, z::AMat; kw...)
|
||||
error("TODO: contours or surfaces... grid")
|
||||
|
||||
# contours or surfaces... matrix grid
|
||||
function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec, y::AVec, zmat::AMat{T}; kw...)
|
||||
# only allow sorted x/y for now
|
||||
# TODO: auto sort x/y/z properly
|
||||
@assert x == sort(x)
|
||||
@assert y == sort(y)
|
||||
@assert size(zmat) == (length(x), length(y))
|
||||
surf = Array(Any,1,1)
|
||||
surf[1,1] = convert(Matrix{Float64}, zmat)
|
||||
createKWargsList(plt, x, y; kw..., surface = surf, linetype = :contour)
|
||||
end
|
||||
|
||||
function createKWargsList(plt::PlottingObject, f::FuncOrFuncs; kw...)
|
||||
error("Can't pass a Function or Vector{Function} for y without also passing x")
|
||||
end
|
||||
|
||||
# list of functions
|
||||
function createKWargsList(plt::PlottingObject, f::FuncOrFuncs, x; kw...)
|
||||
@assert !(typeof(x) <: FuncOrFuncs) # otherwise we'd hit infinite recursion here
|
||||
createKWargsList(plt, x, f; kw...)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
julia 0.3
|
||||
julia 0.4
|
||||
|
||||
Colors
|
||||
Reexport
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user