Compare commits

..

50 Commits

Author SHA1 Message Date
Thomas Breloff fd4dd13270 added svg in pyplot; deprecate qwt; writemime backup for html 2016-03-09 13:36:21 -05:00
Thomas Breloff ded9f332f6 plotlyjs fix 2016-03-09 11:13:31 -05:00
Thomas Breloff d09ca46141 plotlyjs fix 2016-03-09 10:59:33 -05:00
Thomas Breloff b28cd7f8bd plotlyjs fix 2016-03-09 10:23:14 -05:00
Tom Breloff a4054aa500 Merge pull request #159 from jheinen/dev
Fixed some TODOs (Issue $108)
2016-03-09 09:40:06 -05:00
Josef Heinen 3332bfcee1 Fixed some TODOs (Issue $108)
- support the grid keyword
- support handling of NaN (gaps in line segments)
- support xlims/ylims
- removed gr_state macro

The GR.savestate / GR.restorestate problem (caused by exceptions) will be solved
in GR - probably by something like GR.rewind() => to unwind the attribute stack.
2016-03-09 10:34:19 +01:00
Thomas Breloff cc798a0c0a working on plotlyjs 2016-03-09 00:16:16 -05:00
Thomas Breloff fe2030b7e3 working on plotlyjs 2016-03-08 17:52:39 -05:00
Thomas Breloff ed1cce86ef ijulia, plotly, and gr display fixes 2016-03-08 15:07:51 -05:00
Thomas Breloff 9a544b0ff3 warn about Bokeh; 3D parametric plots 2016-03-08 14:18:39 -05:00
Thomas Breloff 82f7b29836 aliases 2016-03-08 13:21:54 -05:00
Thomas Breloff 076acfb242 allow one-sided limits for pyplot 2016-03-07 21:58:01 -05:00
Thomas Breloff ed336bc0ff cleaned up magic args; fixed alphas 2016-03-07 21:38:31 -05:00
Thomas Breloff 5699446d69 winston warning 2016-03-07 20:36:19 -05:00
Thomas Breloff a43d32949e better handling of 3d matrix input 2016-03-07 16:49:13 -05:00
Thomas Breloff 02a1e648bc added gr test; refactored pyplot figure generation, added overwrite_figure arg, closes #144 2016-03-07 15:17:29 -05:00
Thomas Breloff 9d3e0651e2 GR fix handling of Shape; PyPlot marker colors fix (hack), closes #145 2016-03-07 12:57:46 -05:00
Thomas Breloff cdff5a9039 gr_state macro 2016-03-07 12:17:33 -05:00
Tom Breloff ba0b5500ca Merge pull request #149 from jheinen/dev
merging GR updates
2016-03-07 11:21:09 -05:00
Josef Heinen 1439a7e289 Added support for pie charts 2016-03-07 16:36:26 +01:00
Josef Heinen 9761ede5c4 Removed support for hline, vline markers
(not yet implemented)
2016-03-07 16:36:26 +01:00
Josef Heinen e342805752 Added missing marker shapes 2016-03-07 16:36:26 +01:00
Josef Heinen d08672aa71 Improved grid plotting logic 2016-03-07 16:36:26 +01:00
Josef Heinen a3d4e05b0e Improved background color handling 2016-03-07 16:36:26 +01:00
Josef Heinen 51eeed3d50 Improved subplot layout 2016-03-07 16:36:26 +01:00
Josef Heinen 51c45456c3 Disable alpha channel when converting PNGs 2016-03-07 16:36:26 +01:00
Josef Heinen 074ba63bf5 Fill workstation background instead of viewport 2016-03-07 16:36:25 +01:00
Josef Heinen f3d552d8a0 Temporary workaround for multiple mime output 2016-03-07 16:36:25 +01:00
Josef Heinen c5fb4a9228 Added some sanity checks 2016-03-07 16:36:25 +01:00
Josef Heinen 55d7e910e4 Added workaround for multiple mime output 2016-03-07 16:36:25 +01:00
Josef Heinen ea29af8d3d Removed 'private' keyword argument :scale 2016-03-07 16:36:25 +01:00
Thomas Breloff 88b9d71bd7 fixed default PyPlot gradient 2016-03-07 09:55:05 -05:00
Thomas Breloff 165c84c246 pyplot minmax fix; convertToAnyVector fix 2016-03-04 12:46:33 -05:00
Thomas Breloff 347820867d pyplot lim fixes 2016-03-03 21:43:08 -05:00
Thomas Breloff 26d0dfbf3d Merge branch 'dev' of github.com:tbreloff/Plots.jl into dev 2016-03-03 16:06:03 -05:00
Thomas Breloff 6aa4849266 pyplot lims udpate fix 2016-03-03 16:05:27 -05:00
Thomas Breloff 335b3802b8 added FixedSizeArrays requirement 2016-03-02 22:48:27 -05:00
Thomas Breloff 73bd3fa60c curves 2016-02-22 22:53:31 -05:00
Thomas Breloff 6b61c5900c generalize curves 2016-02-22 10:39:03 -05:00
Thomas Breloff 9da4083096 directed_curve 2016-02-20 20:57:56 -05:00
Thomas Breloff 86fe244d95 revert pyplot changes 2016-02-19 21:59:43 -05:00
Thomas Breloff 732f2846de directed_curve; working on PyPlot fixes 2016-02-19 18:24:56 -05:00
Thomas Breloff 4f238caf5c added annotation options 2016-02-18 22:59:31 -05:00
Thomas Breloff c9388e9f56 bezier curves 2016-02-18 18:28:59 -05:00
Thomas Breloff 2a9fa9539f fixes to logic accepting arrays of values; additional fixes in gadfly and pyplot for this 2016-02-17 10:32:12 -05:00
Thomas Breloff b8d136588c gif macro and every/when syntax 2016-02-16 18:02:04 -05:00
Thomas Breloff 92c9e82dee fix refdir 2016-02-16 16:45:46 -05:00
Thomas Breloff 0fdb48bda3 fixes for ticks 2016-02-16 16:22:54 -05:00
Thomas Breloff e8d4fd7aac skip pyplot test 4 2016-02-12 15:41:00 -05:00
Thomas Breloff 6a4a78a26a skip pyplot test 13 2016-02-12 15:17:31 -05:00
20 changed files with 753 additions and 244 deletions
+1
View File
@@ -4,3 +4,4 @@ Colors
Reexport
Compat
Requires
FixedSizeArrays
+9 -29
View File
@@ -7,6 +7,7 @@ using Compat
using Reexport
@reexport using Colors
using Requires
using FixedSizeArrays
export
Plot,
@@ -116,6 +117,7 @@ export
frame,
gif,
@animate,
@gif,
# recipes
PlotRecipe,
@@ -221,38 +223,16 @@ yaxis!(plt::Plot, args...; kw...) = plot!(pl
# ---------------------------------------------------------
# try
# import DataFrames
# dataframes()
# end
# const CURRENT_BACKEND = pickDefaultBackend()
# for be in backends()
# try
# backend(be)
# backend()
# catch err
# @show err
# end
# end
const CURRENT_BACKEND = CurrentBackend(:none)
# function __init__()
# # global const CURRENT_BACKEND = pickDefaultBackend()
# # global const CURRENT_BACKEND = CurrentBackend(:none)
function __init__()
# # global CURRENT_BACKEND
# # println("[Plots.jl] Default backend: ", CURRENT_BACKEND.sym)
# # # auto init dataframes if the import statement doesn't error out
# # try
# # @eval import DataFrames
# # dataframes()
# # end
# end
# override IJulia inline display
if isijulia()
@eval import IJulia
IJulia.display_dict(plt::PlottingObject) = Dict{ASCIIString, ByteString}("text/html" => sprint(writemime, "text/html", plt))
end
end
# ---------------------------------------------------------
+67 -17
View File
@@ -31,7 +31,7 @@ function gif(anim::Animation, fn::@compat(AbstractString) = "tmp.gif"; fps::Inte
# high quality
speed = round(Int, 100 / fps)
run(`convert -delay $speed -loop 0 $(anim.dir)/*.png $fn`)
run(`convert -delay $speed -loop 0 $(anim.dir)/*.png -alpha off $fn`)
catch err
warn("Tried to create gif using convert (ImageMagick), but got error: $err\nWill try ffmpeg, but it's lower quality...)")
@@ -55,6 +55,69 @@ end
# -----------------------------------------------
function _animate(forloop::Expr, args...; callgif = false)
if forloop.head != :for
error("@animate macro expects a for-block. got: $(forloop.head)")
end
# add the call to frame to the end of each iteration
animsym = gensym("anim")
countersym = gensym("counter")
block = forloop.args[2]
# create filter
n = length(args)
filterexpr = if n == 0
# no filter... every iteration gets a frame
true
elseif args[1] == :every
# filter every `freq` frames (starting with the first frame)
@assert n == 2
freq = args[2]
@assert isa(freq, Integer) && freq > 0
:(mod1($countersym, $freq) == 1)
elseif args[1] == :when
# filter on custom expression
@assert n == 2
args[2]
else
error("Unsupported animate filter: $args")
end
push!(block.args, :(if $filterexpr; frame($animsym); end))
push!(block.args, :($countersym += 1))
# add a final call to `gif(anim)`?
retval = callgif ? :(gif($animsym)) : animsym
# full expression:
esc(quote
$animsym = Animation() # init animation object
$countersym = 1 # init iteration counter
$forloop # for loop, saving a frame after each iteration
$retval # return the animation object, or the gif
end)
end
"""
Builds an `Animation` using one frame per loop iteration, then create an animated GIF.
Example:
```
p = plot(1)
@gif for x=0:0.1:5
push!(p, 1, sin(x))
end
```
"""
macro gif(forloop::Expr, args...)
_animate(forloop, args...; callgif = true)
end
"""
Collect one frame per for-block iteration and return an `Animation` object.
@@ -65,22 +128,9 @@ Example:
anim = @animate for x=0:0.1:5
push!(p, 1, sin(x))
end
gif(anim)
```
"""
macro animate(forloop::Expr)
if forloop.head != :for
error("@animate macro expects a for-block. got: $(forloop.head)")
end
# add the call to frame to the end of each iteration
animsym = gensym("anim")
block = forloop.args[2]
push!(block.args, :(frame($animsym)))
# full expression:
esc(quote
$animsym = Animation() # init animation object
$forloop # for loop, saving a frame after each iteration
$animsym # return the animation object
end)
macro animate(forloop::Expr, args...)
_animate(forloop, args...)
end
+58 -24
View File
@@ -179,14 +179,14 @@ _plotDefaults[:tickfont] = font(8)
_plotDefaults[:guidefont] = font(11)
_plotDefaults[:legendfont] = font(8)
_plotDefaults[:grid] = true
_plotDefaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
_plotDefaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
_plotDefaults[:overwrite_figure] = false
# TODO: x/y scales
const _allArgs = sort(collect(union(keys(_seriesDefaults), keys(_plotDefaults))))
supportedArgs(::PlottingPackage) = _allArgs
supportedArgs(::PlottingPackage) = error("supportedArgs not defined") #_allArgs
supportedArgs() = supportedArgs(backend())
@@ -232,6 +232,7 @@ end
:type => :linetype,
:lt => :linetype,
:t => :linetype,
:seriestype => :linetype,
:style => :linestyle,
:s => :linestyle,
:ls => :linestyle,
@@ -307,6 +308,14 @@ end
:palette => :color_palette,
:xlink => :linkx,
:ylink => :linky,
:nrow => :nr,
:nrows => :nr,
:ncol => :nc,
:ncols => :nc,
:clf => :overwrite_figure,
:clearfig => :overwrite_figure,
:overwrite => :overwrite_figure,
:reuse => :overwrite_figure,
)
# add all pluralized forms to the _keyAliases dict
@@ -356,12 +365,6 @@ end
# -----------------------------------------------------------------------------
wraptuple(x::@compat(Tuple)) = x
wraptuple(x) = (x,)
trueOrAllTrue(f::Function, x::AbstractArray) = all(f, x)
trueOrAllTrue(f::Function, x) = f(x)
function handleColors!(d::Dict, arg, csym::Symbol)
try
if arg == :auto
@@ -413,11 +416,13 @@ end
function processLineArg(d::Dict, arg)
# linetype
if trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
# if trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
if allLineTypes(arg)
d[:linetype] = arg
# linestyle
elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
# elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
elseif allStyles(arg)
d[:linestyle] = arg
elseif typeof(arg) <: Stroke
@@ -432,11 +437,13 @@ function processLineArg(d::Dict, arg)
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
# linealpha
elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
elseif allAlphas(arg)
d[:linealpha] = arg
# linewidth
elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
# elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
elseif allReals(arg)
d[:linewidth] = arg
# color
@@ -450,13 +457,16 @@ end
function processMarkerArg(d::Dict, arg)
# markershape
if trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg)
d[:markershape] = arg
elseif trueOrAllTrue(a -> isa(a, Shape), arg)
# if trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg)
# d[:markershape] = arg
# elseif trueOrAllTrue(a -> isa(a, Shape), arg)
if allShapes(arg)
d[:markershape] = arg
# stroke style
elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
# elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
elseif allStyles(arg)
d[:markerstrokestyle] = arg
elseif typeof(arg) <: Stroke
@@ -471,11 +481,13 @@ function processMarkerArg(d::Dict, arg)
arg.alpha == nothing || (d[:markeralpha] = arg.alpha)
# linealpha
elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
elseif allAlphas(arg)
d[:markeralpha] = arg
# markersize
elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
# elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
elseif allReals(arg)
d[:markersize] = arg
# markercolor
@@ -494,11 +506,13 @@ function processFillArg(d::Dict, arg)
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
# fillrange function
elseif trueOrAllTrue(a -> isa(a, Function), arg)
# elseif trueOrAllTrue(a -> isa(a, Function), arg)
elseif allFunctions(arg)
d[:fillrange] = arg
# fillalpha
elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
elseif allAlphas(arg)
d[:fillalpha] = arg
elseif !handleColors!(d, arg, :fillcolor)
@@ -507,6 +521,11 @@ function processFillArg(d::Dict, arg)
end
end
_replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape)
_replace_markershape(shapes::AVec) = map(_replace_markershape, shapes)
_replace_markershape(shape) = shape
"Handle all preprocessing of args... break out colors/sizes/etc and replace aliases."
function preprocessArgs!(d::Dict)
replaceAliases!(d, _keyAliases)
@@ -518,6 +537,12 @@ function preprocessArgs!(d::Dict)
processAxisArg(d, axisletter, arg)
end
delete!(d, asym)
# turn :labels into :ticks_and_labels
tsym = symbol(axisletter * "ticks")
if haskey(d, tsym) && ticksType(d[tsym]) == :labels
d[tsym] = (1:length(d[tsym]), d[tsym])
end
end
# handle line args
@@ -533,7 +558,12 @@ function preprocessArgs!(d::Dict)
anymarker = true
end
delete!(d, :marker)
if anymarker && !haskey(d, :markershape)
# if anymarker && !haskey(d, :markershape)
# d[:markershape] = :ellipse
# end
if haskey(d, :markershape)
d[:markershape] = _replace_markershape(d[:markershape])
elseif anymarker
d[:markershape] = :ellipse
end
@@ -613,6 +643,9 @@ function warnOnUnsupportedArgs(pkg::PlottingPackage, d::Dict)
end
end
_markershape_supported(pkg::PlottingPackage, shape::Symbol) = shape in supportedMarkers(pkg)
_markershape_supported(pkg::PlottingPackage, shape::Shape) = Shape in supportedMarkers(pkg)
_markershape_supported(pkg::PlottingPackage, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
function warnOnUnsupported(pkg::PlottingPackage, d::Dict)
(d[:axis] in supportedAxes(pkg)
@@ -623,8 +656,9 @@ function warnOnUnsupported(pkg::PlottingPackage, d::Dict)
(d[:linestyle] in supportedStyles(pkg)
|| warn("linestyle $(d[:linestyle]) is unsupported with $pkg. Choose from: $(supportedStyles(pkg))"))
(d[:markershape] == :none
|| d[:markershape] in supportedMarkers(pkg)
|| (Shape in supportedMarkers(pkg) && typeof(d[:markershape]) <: Shape)
|| _markershape_supported(pkg, d[:markershape])
# || d[:markershape] in supportedMarkers(pkg)
# || (Shape in supportedMarkers(pkg) && typeof(d[:markershape]) <: Shape)
|| warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supportedMarkers(pkg))"))
end
+1
View File
@@ -4,6 +4,7 @@
function _initialize_backend(::BokehPackage; kw...)
@eval begin
warn("Bokeh is no longer supported... many features will likely be broken.")
import Bokeh
export Bokeh
end
+10 -5
View File
@@ -168,11 +168,16 @@ end
# ---------------------------------------------------------------------------
# extract the underlying ShapeGeometry object(s)
getMarkerGeom(shape::Shape) = gadflyshape(shape)
getMarkerGeom(shape::Symbol) = gadflyshape(_shapes[shape])
getMarkerGeom(shapes::AVec) = map(getMarkerGeom, shapes)
getMarkerGeom(d::Dict) = getMarkerGeom(d[:markershape])
function getMarkerGeom(d::Dict)
shape = d[:markershape]
gadflyshape(isa(shape, Shape) ? shape : _shapes[shape])
end
# function getMarkerGeom(d::Dict)
# shape = d[:markershape]
# gadflyshape(isa(shape, Shape) ? shape : _shapes[shape])
# end
function getGadflyMarkerTheme(d::Dict, plotargs::Dict)
@@ -369,7 +374,7 @@ function addGadflyTicksGuide(gplt, ticks, isx::Bool)
gfunc = isx ? Gadfly.Scale.x_discrete : Gadfly.Scale.y_discrete
labelmap = Dict(zip(ticks...))
labelfunc = val -> labelmap[val]
push!(gplt.scales, gfunc(levels = ticks[1], labels = labelfunc))
push!(gplt.scales, gfunc(levels = collect(ticks[1]), labels = labelfunc))
else
error("Invalid input for $(isx ? "xticks" : "yticks"): ", ticks)
+241 -74
View File
@@ -1,7 +1,6 @@
# https://github.com/jheinen/GR.jl
function _initialize_backend(::GRPackage; kw...)
@eval begin
import GR
@@ -9,15 +8,16 @@ function _initialize_backend(::GRPackage; kw...)
end
end
const gr_linetype = Dict(
:auto => 1, :solid => 1, :dash => 2, :dot => 3, :dashdot => 4,
:dashdotdot => -1 )
const gr_markertype = Dict(
:auto => 1, :none => -1, :ellipse => -1, :rect => -7, :diamond => -13,
:utriangle => -3, :dtriangle => -5, :pentagon => -14, :hexagon => 3,
:cross => 2, :xcross => 5, :star5 => 3 )
:utriangle => -3, :dtriangle => -5, :pentagon => -21, :hexagon => -22,
:heptagon => -23, :octagon => -24, :cross => 2, :xcross => 5,
:star4 => -25, :star5 => -26, :star6 => -27, :star7 => -28, :star8 => -29,
:vline => -30, :hline => -31 )
const gr_halign = Dict(:left => 1, :hcenter => 2, :right => 3)
const gr_valign = Dict(:top => 1, :vcenter => 3, :bottom => 5)
@@ -40,6 +40,55 @@ function gr_getaxisind(p)
end
end
function gr_setmarkershape(p)
if haskey(p, :markershape)
shape = p[:markershape]
if isa(shape, Shape)
p[:vertices] = shape.vertices
else
GR.setmarkertype(gr_markertype[shape])
p[:vertices] = :none
end
end
end
function gr_polymarker(p, x, y)
if p[:vertices] != :none
vertices= p[:vertices]
dx = Float64[el[1] for el in vertices] * 0.01
dy = Float64[el[2] for el in vertices] * 0.01
GR.selntran(0)
GR.setfillcolorind(gr_getcolorind(p[:markercolor]))
GR.setfillintstyle(GR.INTSTYLE_SOLID)
for i = 1:length(x)
xn, yn = GR.wctondc(x[i], y[i])
GR.fillarea(xn + dx, yn + dy)
end
GR.selntran(1)
else
GR.polymarker(x, y)
end
end
function gr_polyline(x, y)
if NaN in x || NaN in y
i = 1
j = 1
n = length(x)
while i < n
while j < n && x[j] != Nan && y[j] != NaN
j += 1
end
if i < j
GR.polyline(x[i:j], y[i:j])
end
i = j + 1
end
else
GR.polyline(x, y)
end
end
function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
subplot=[0, 1, 0, 1])
d = plt.plotargs
@@ -54,25 +103,48 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
msize = mwidth * w / width
GR.setwsviewport(0, msize, 0, msize * ratio)
GR.setwswindow(0, 1, 0, ratio)
viewport[1] = subplot[1] + 0.1 * (subplot[2] - subplot[1])
viewport[2] = subplot[1] + 0.95 * (subplot[2] - subplot[1])
viewport[3] = ratio * (subplot[3] + 0.1 * (subplot[4] - subplot[3]))
viewport[4] = ratio * (subplot[3] + 0.95 * (subplot[4] - subplot[3]))
viewport[1] = subplot[1] + 0.125 * (subplot[2] - subplot[1])
viewport[2] = subplot[1] + 0.95 * (subplot[2] - subplot[1])
viewport[3] = ratio * (subplot[3] + 0.125 * (subplot[4] - subplot[3]))
viewport[4] = ratio * (subplot[3] + 0.95 * (subplot[4] - subplot[3]))
else
ratio = float(w) / h
msize = mheight * h / height
GR.setwsviewport(0, msize * ratio, 0, msize)
GR.setwswindow(0, ratio, 0, 1)
viewport[1] = ratio * (subplot[1] + 0.1 * (subplot[2] - subplot[1]))
viewport[2] = ratio * (subplot[1] + 0.95 * (subplot[2] - subplot[1]))
viewport[3] = subplot[3] + 0.1 * (subplot[4] - subplot[3])
viewport[4] = subplot[3] + 0.95 * (subplot[4] - subplot[3])
viewport[1] = ratio * (subplot[1] + 0.125 * (subplot[2] - subplot[1]))
viewport[2] = ratio * (subplot[1] + 0.95 * (subplot[2] - subplot[1]))
viewport[3] = subplot[3] + 0.125 * (subplot[4] - subplot[3])
viewport[4] = subplot[3] + 0.95 * (subplot[4] - subplot[3])
end
if haskey(d, :background_color)
GR.savestate()
GR.selntran(0)
GR.setfillintstyle(GR.INTSTYLE_SOLID)
GR.setfillcolorind(gr_getcolorind(d[:background_color]))
if w > h
GR.fillrect(subplot[1], subplot[2], ratio*subplot[3], ratio*subplot[4])
else
GR.fillrect(ratio*subplot[1], ratio*subplot[2], subplot[3], subplot[4])
end
GR.selntran(1)
GR.restorestate()
c = getColor(d[:background_color])
if 0.21 * c.r + 0.72 * c.g + 0.07 * c.b < 0.9
fg = convert(Int, GR.inqcolorfromrgb(1-c.r, 1-c.g, 1-c.b))
else
fg = 1
end
else
fg = 1
end
extrema = zeros(2, 4)
num_axes = 1
cmap = false
axes_2d = true
grid_flag = get(d, :grid, true)
for axis = 1:2
xmin = ymin = typemax(Float64)
@@ -99,6 +171,10 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
end
cmap = true
x, y, H = Base.hist2d(E, xbins, ybins)
elseif p[:linetype] == :pie
axes_2d = false
xmin, xmax, ymin, ymax = 0, 1, 0, 1
x, y = p[:x], p[:y]
else
if p[:linetype] in [:contour, :surface]
cmap = true
@@ -108,31 +184,50 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
end
x, y = p[:x], p[:y]
end
xmin = min(minimum(x), xmin)
xmax = max(maximum(x), xmax)
if p[:linetype] == :ohlc
for val in y
ymin = min(val.open, val.high, val.low, val.close, ymin)
ymax = max(val.open, val.high, val.low, val.close, ymax)
if p[:linetype] != :pie
xmin = min(minimum(x), xmin)
xmax = max(maximum(x), xmax)
if p[:linetype] == :ohlc
for val in y
ymin = min(val.open, val.high, val.low, val.close, ymin)
ymax = max(val.open, val.high, val.low, val.close, ymax)
end
else
ymin = min(minimum(y), ymin)
ymax = max(maximum(y), ymax)
end
else
ymin = min(minimum(y), ymin)
ymax = max(maximum(y), ymax)
end
end
end
if d[:xlims] != :auto
xmin, xmax = d[:xlims]
end
if d[:ylims] != :auto
ymin, ymax = d[:ylims]
end
if xmax <= xmin
xmax = xmin + 1
end
if ymax <= ymin
ymax = ymin + 1
end
extrema[axis,:] = [xmin, xmax, ymin, ymax]
end
if num_axes == 2 || !axes_2d
viewport[2] -= 0.05
viewport[2] -= 0.0525
end
if cmap
viewport[2] -= 0.1
end
GR.setviewport(viewport[1], viewport[2], viewport[3], viewport[4])
scale = d[:scale]
scale = 0
d[:xscale] == :log10 && (scale |= GR.OPTION_X_LOG)
d[:yscale] == :log10 && (scale |= GR.OPTION_Y_LOG)
get(d, :xflip, false) && (scale |= GR.OPTION_FLIP_X)
get(d, :yflip, false) && (scale |= GR.OPTION_FLIP_Y)
for axis = 1:num_axes
xmin, xmax, ymin, ymax = extrema[axis,:]
if scale & GR.OPTION_X_LOG == 0
@@ -161,22 +256,20 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
end
GR.setwindow(xmin, xmax, ymin, ymax)
if axis == 1 && haskey(d, :background_color)
GR.savestate()
GR.setfillintstyle(GR.INTSTYLE_SOLID)
GR.setfillcolorind(gr_getcolorind(d[:background_color]))
GR.fillrect(xmin, xmax, ymin, ymax)
GR.restorestate()
end
GR.setscale(scale)
diag = sqrt((viewport[2] - viewport[1])^2 + (viewport[4] - viewport[3])^2)
charheight = max(0.018 * diag, 0.01)
GR.setcharheight(charheight)
GR.settextcolorind(fg)
if axes_2d
diag = sqrt((viewport[2] - viewport[1])^2 + (viewport[4] - viewport[3])^2)
GR.setlinewidth(1)
charheight = max(0.018 * diag, 0.01)
GR.setcharheight(charheight)
GR.setlinecolorind(fg)
ticksize = 0.0075 * diag
GR.grid(xtick, ytick, 0, 0, majorx, majory)
if grid_flag && fg == 1
GR.grid(xtick, ytick, 0, 0, majorx, majory)
end
if num_axes == 1
GR.axes(xtick, ytick, xorg[1], yorg[1], majorx, majory, ticksize)
GR.axes(xtick, ytick, xorg[2], yorg[2], -majorx, -majory, -ticksize)
@@ -191,19 +284,22 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
if get(d, :title, "") != ""
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.text(0.5, min(ratio, 1), d[:title])
GR.settextcolorind(fg)
GR.text(0.5 * (viewport[1] + viewport[2]), min(ratio, 1), d[:title])
GR.restorestate()
end
if get(d, :xlabel, "") != ""
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
GR.text(0.5, 0, d[:xlabel])
GR.settextcolorind(fg)
GR.text(0.5 * (viewport[1] + viewport[2]), 0, d[:xlabel])
GR.restorestate()
end
if get(d, :ylabel, "") != ""
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.setcharup(-1, 0)
GR.settextcolorind(fg)
GR.text(0, 0.5 * (viewport[3] + viewport[4]), d[:ylabel])
GR.restorestate()
end
@@ -211,6 +307,7 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.setcharup(1, 0)
GR.settextcolorind(fg)
GR.text(1, 0.5 * (viewport[3] + viewport[4]), d[:yrightlabel])
GR.restorestate()
end
@@ -231,14 +328,18 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
GR.setfillcolorind(gr_getcolorind(p[:fillcolor]))
GR.setfillintstyle(GR.INTSTYLE_SOLID)
end
if p[:fillrange] != nothing
GR.fillarea([p[:x][1]; p[:x]; p[:x][length(p[:x])]], [p[:fillrange]; p[:y]; p[:fillrange]])
if length(p[:x]) > 1
if p[:fillrange] != nothing
GR.fillarea([p[:x][1]; p[:x]; p[:x][length(p[:x])]], [p[:fillrange]; p[:y]; p[:fillrange]])
end
GR.polyline(p[:x], p[:y])
end
GR.polyline(p[:x], p[:y])
legend = true
end
if p[:linetype] == :line
GR.polyline(p[:x], p[:y])
if length(p[:x]) > 1
gr_polyline(p[:x], p[:y])
end
legend = true
elseif p[:linetype] in [:steppre, :steppost]
n = length(p[:x])
@@ -256,7 +357,9 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
end
j += 2
end
GR.polyline(x, y)
if n > 1
GR.polyline(x, y)
end
legend = true
elseif p[:linetype] == :sticks
x, y = p[:x], p[:y]
@@ -266,11 +369,13 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
legend = true
elseif p[:linetype] == :scatter || (p[:markershape] != :none && axes_2d)
haskey(p, :markercolor) && GR.setmarkercolorind(gr_getcolorind(p[:markercolor]))
haskey(p, :markershape) && GR.setmarkertype(gr_markertype[p[:markershape]])
gr_setmarkershape(p)
if haskey(d, :markersize)
if typeof(d[:markersize]) <: Number
GR.setmarkersize(d[:markersize] / 4.0)
GR.polymarker(p[:x], p[:y])
if length(p[:x]) > 0
gr_polymarker(p, p[:x], p[:y])
end
else
c = p[:markercolor]
GR.setcolormap(-GR.COLORMAP_GLOWING)
@@ -280,11 +385,13 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
GR.setmarkercolorind(ci)
end
GR.setmarkersize(d[:markersize][i] / 4.0)
GR.polymarker([p[:x][i]], [p[:y][i]])
gr_polymarker(p, [p[:x][i]], [p[:y][i]])
end
end
else
GR.polymarker(p[:x], p[:y])
if length(p[:x]) > 0
gr_polymarker(p, p[:x], p[:y])
end
end
legend = true
elseif p[:linetype] == :bar
@@ -368,11 +475,11 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
diag = sqrt((viewport[2] - viewport[1])^2 + (viewport[4] - viewport[3])^2)
charheight = max(0.018 * diag, 0.01)
ticksize = 0.01 * (viewport[2] - viewport[1])
# GR.savestate()
GR.setlinewidth(1)
GR.grid3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2)
GR.grid3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0)
# GR.restorestate()
if grid_flag
GR.grid3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2)
GR.grid3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0)
end
z = reshape(z, length(x) * length(y))
if p[:linetype] == :surface
GR.setcolormap(GR.COLORMAP_COOLWARM)
@@ -400,21 +507,23 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
diag = sqrt((viewport[2] - viewport[1])^2 + (viewport[4] - viewport[3])^2)
charheight = max(0.018 * diag, 0.01)
ticksize = 0.01 * (viewport[2] - viewport[1])
# GR.savestate()
GR.setlinewidth(1)
GR.grid3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2)
GR.grid3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0)
# GR.restorestate()
if grid_flag && p[:linetype] == :path3d
GR.grid3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2)
GR.grid3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0)
end
if p[:linetype] == :scatter3d
haskey(p, :markercolor) && GR.setmarkercolorind(gr_getcolorind(p[:markercolor]))
haskey(p, :markershape) && GR.setmarkertype(gr_markertype[p[:markershape]])
gr_setmarkershape(p)
for i = 1:length(z)
px, py = GR.wc3towc(x[i], y[i], z[i])
GR.polymarker([px], [py])
gr_polymarker(p, [px], [py])
end
else
haskey(p, :linewidth) && GR.setlinewidth(p[:linewidth])
GR.polyline3d(x, y, z)
if length(x) > 0
GR.polyline3d(x, y, z)
end
end
GR.setlinewidth(1)
GR.setcharheight(charheight)
@@ -429,8 +538,51 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
GR.polyline([i, i], [y[i].low, y[i].high])
GR.polyline([i, i+ticksize], [y[i].close, y[i].close])
end
elseif p[:linetype] in [:pie]
println("TODO: add support for linetype $(p[:linetype])")
elseif p[:linetype] == :pie
GR.selntran(0)
GR.setfillintstyle(GR.INTSTYLE_SOLID)
xmin, xmax, ymin, ymax = viewport
ymax -= 0.05 * (xmax - xmin)
xcenter = 0.5 * (xmin + xmax)
ycenter = 0.5 * (ymin + ymax)
if xmax - xmin > ymax - ymin
r = 0.5 * (ymax - ymin)
xmin, xmax = xcenter - r, xcenter + r
else
r = 0.5 * (xmax - xmin)
ymin, ymax = ycenter - r, ycenter + r
end
labels, slices = p[:x], p[:y]
numslices = length(slices)
total = sum(slices)
a1 = 0
x = zeros(3)
y = zeros(3)
for i in 1:numslices
a2 = round(Int, a1 + (slices[i] / total) * 360.0)
GR.setfillcolorind(980 + (i-1) % 20)
GR.fillarc(xmin, xmax, ymin, ymax, a1, a2)
alpha = 0.5 * (a1 + a2)
cosf = r * cos(alpha * pi / 180)
sinf = r * sin(alpha * pi / 180)
x[1] = xcenter + cosf
y[1] = ycenter + sinf
x[2] = x[1] + 0.1 * cosf
y[2] = y[1] + 0.1 * sinf
y[3] = y[2]
if 90 <= alpha < 270
x[3] = x[2] - 0.05
GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF)
GR.text(x[3] - 0.01, y[3], string(labels[i]))
else
x[3] = x[2] + 0.05
GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
GR.text(x[3] + 0.01, y[3], string(labels[i]))
end
GR.polyline(x, y)
a1 = a2
end
GR.selntran(1)
end
GR.restorestate()
end
@@ -453,13 +605,13 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
end
px = viewport[2] - 0.05 - w
py = viewport[4] - 0.06
dy = 0.03 * sqrt((viewport[2] - viewport[1])^2 + (viewport[4] - viewport[3])^2)
GR.setfillintstyle(GR.INTSTYLE_SOLID)
GR.setfillcolorind(0)
GR.fillrect(px - 0.08, px + w + 0.02, py + 0.03, py - 0.03 * length(plt.seriesargs))
GR.fillrect(px - 0.08, px + w + 0.02, py + dy, py - dy * length(plt.seriesargs))
GR.setlinetype(1)
GR.setlinecolorind(1)
GR.setlinewidth(1)
GR.drawrect(px - 0.08, px + w + 0.02, py + 0.03, py - 0.03 * length(plt.seriesargs))
GR.drawrect(px - 0.08, px + w + 0.02, py + dy, py - dy * length(plt.seriesargs))
haskey(d, :linewidth) && GR.setlinewidth(d[:linewidth])
i = 0
for p in plt.seriesargs
@@ -470,11 +622,11 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
end
if p[:linetype] == :scatter || p[:markershape] != :none
haskey(p, :markercolor) && GR.setmarkercolorind(gr_getcolorind(p[:markercolor]))
haskey(p, :markershape) && GR.setmarkertype(gr_markertype[p[:markershape]])
gr_setmarkershape(p)
if p[:linetype] in [:path, :line, :steppre, :steppost, :sticks]
GR.polymarker([px - 0.06, px - 0.02], [py, py])
gr_polymarker(p, [px - 0.06, px - 0.02], [py, py])
else
GR.polymarker([px - 0.06, px - 0.04, px - 0.02], [py, py, py])
gr_polymarker(p, [px - 0.06, px - 0.04, px - 0.02], [py, py, py])
end
end
if typeof(p[:label]) <: Array
@@ -484,8 +636,9 @@ function gr_display(plt::Plot{GRPackage}, clear=true, update=true,
lab = p[:label]
end
GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
GR.settextcolorind(1)
GR.text(px, py, lab)
py -= 0.03
py -= dy
end
GR.selntran(1)
GR.restorestate()
@@ -530,7 +683,6 @@ function gr_display(subplt::Subplot{GRPackage})
end
function _create_plot(pkg::GRPackage; kw...)
isijulia() && GR.inline("svg")
d = Dict(kw)
Plot(nothing, pkg, 0, d, Dict[])
end
@@ -555,13 +707,6 @@ function _before_update_plot(plt::Plot{GRPackage})
end
function _update_plot(plt::Plot{GRPackage}, d::Dict)
scale = 0
d[:xscale] == :log10 && (scale |= GR.OPTION_X_LOG)
d[:yscale] == :log10 && (scale |= GR.OPTION_Y_LOG)
get(d, :xflip, false) && (scale |= GR.OPTION_FLIP_X)
get(d, :yflip, false) && (scale |= GR.OPTION_FLIP_Y)
plt.plotargs[:scale] = scale
for k in (:title, :xlabel, :ylabel)
haskey(d, k) && (plt.plotargs[k] = d[k])
end
@@ -600,6 +745,7 @@ end
# ----------------------------------------------------------------
function Base.writemime(io::IO, m::MIME"image/png", plt::PlottingObject{GRPackage})
GR.emergencyclosegks()
ENV["GKS_WSTYPE"] = "png"
gr_display(plt)
GR.emergencyclosegks()
@@ -607,17 +753,38 @@ function Base.writemime(io::IO, m::MIME"image/png", plt::PlottingObject{GRPackag
end
function Base.writemime(io::IO, m::MIME"image/svg+xml", plt::PlottingObject{GRPackage})
isijulia() || return
GR.emergencyclosegks()
ENV["GKS_WSTYPE"] = "svg"
gr_display(plt)
GR.emergencyclosegks()
write(io, readall("gks.svg"))
end
function Base.writemime(io::IO, m::MIME"text/html", plt::PlottingObject{GRPackage})
writemime(io, MIME("image/svg+xml"), plt)
end
function Base.writemime(io::IO, m::MIME"application/pdf", plt::PlottingObject{GRPackage})
GR.emergencyclosegks()
ENV["GKS_WSTYPE"] = "pdf"
gr_display(plt)
GR.emergencyclosegks()
write(io, readall("gks.pdf"))
end
function Base.writemime(io::IO, m::MIME"application/postscript", plt::PlottingObject{GRPackage})
GR.emergencyclosegks()
ENV["GKS_WSTYPE"] = "ps"
gr_display(plt)
GR.emergencyclosegks()
write(io, readall("gks.ps"))
end
function Base.display(::PlotsDisplay, plt::Plot{GRPackage})
gr_display(plt)
end
function Base.display(::PlotsDisplay, plt::Subplot{GRPackage})
gr_display(plt)
true
end
+1 -9
View File
@@ -27,11 +27,6 @@ function _initialize_backend(::PlotlyPackage; kw...)
# end borrowing (thanks :)
###########################
# try
# include(joinpath(Pkg.dir("Plots"), "src", "backends", "plotly_blink.jl"))
# catch err
# warn("Error including PlotlyJS: $err\n Note: Will fall back to built-in display.")
# end
end
# TODO: other initialization
end
@@ -462,11 +457,8 @@ end
# ----------------------------------------------------------------
function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{PlotlyPackage})
isijulia() && return
# TODO: write a png to io
println("todo: png")
warn("todo: png")
end
function Base.writemime(io::IO, ::MIME"text/html", plt::PlottingObject{PlotlyPackage})
+30 -18
View File
@@ -8,8 +8,12 @@ function _initialize_backend(::PlotlyJSPackage; kw...)
end
for (mime, fmt) in PlotlyJS._mimeformats
@eval Base.writemime(io::IO, m::MIME{symbol($mime)}, p::Plot{PlotlyJSPackage}) =
writemime(io, m, p.o)
@eval Base.writemime(io::IO, m::MIME{symbol($mime)}, p::Plot{PlotlyJSPackage}) = writemime(io, m, p.o)
end
# override IJulia inline display
if isijulia()
IJulia.display_dict(plt::PlottingObject{PlotlyJSPackage}) = IJulia.display_dict(plt.o)
end
end
@@ -19,8 +23,11 @@ function _create_plot(pkg::PlotlyJSPackage; kw...)
d = Dict(kw)
# TODO: create the window/canvas/context that is the plot within the backend (call it `o`)
# TODO: initialize the plot... title, xlabel, bgcolor, etc
o = PlotlyJS.Plot(PlotlyJS.GenericTrace[], PlotlyJS.Layout(),
Base.Random.uuid4(), PlotlyJS.ElectronDisplay())
# o = PlotlyJS.Plot(PlotlyJS.GenericTrace[], PlotlyJS.Layout(),
# Base.Random.uuid4(), PlotlyJS.ElectronDisplay())
# T = isijulia() ? PlotlyJS.JupyterPlot : PlotlyJS.ElectronPlot
# o = T(PlotlyJS.Plot())
o = PlotlyJS.plot()
Plot(o, pkg, 0, d, Dict[])
end
@@ -28,15 +35,15 @@ end
function _add_series(::PlotlyJSPackage, plt::Plot; kw...)
d = Dict(kw)
syncplot = plt.o
# dumpdict(d, "addseries", true)
# add to the data array
pdict = plotly_series(d)
typ = pop!(pdict, :type)
gt = PlotlyJS.GenericTrace(typ; pdict...)
push!(plt.o.data, gt)
if PlotlyJS.isactive(plt.o._display)
PlotlyJS.addtraces!(plt.o, gt)
end
PlotlyJS.addtraces!(syncplot, gt)
push!(plt.seriesargs, d)
plt
@@ -47,12 +54,11 @@ end
function _add_annotations{X,Y,V}(plt::Plot{PlotlyJSPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
# set or add to the annotation_list
if haskey(plt.plotargs, :annotation_list)
# set or add to the annotation_list
if !haskey(plt.plotargs, :annotation_list)
plt.plotargs[:annotation_list] = Any[]
end
append!(plt.plotargs[:annotation_list], anns)
else
plt.plotargs[:annotation_list] = anns
end
end
# ----------------------------------------------------------------
@@ -63,10 +69,10 @@ end
# TODO: override this to update plot items (title, xlabel, etc) after creation
function _update_plot(plt::Plot{PlotlyJSPackage}, d::Dict)
pdict = plotly_layout(d)
plt.o.layout = PlotlyJS.Layout(pdict)
if PlotlyJS.isactive(plt.o._display)
PlotlyJS.relayout!(plt.o; pdict...)
end
# dumpdict(pdict, "pdict updateplot", true)
syncplot = plt.o
w,h = d[:size]
PlotlyJS.relayout!(syncplot, pdict, width = w, height = h)
end
@@ -85,6 +91,9 @@ end
function Base.setindex!(plt::Plot{PlotlyJSPackage}, xy::Tuple, i::Integer)
d = plt.seriesargs[i]
d[:x], d[:y] = xy
# TODO: this is likely ineffecient... we should make a call that ONLY changes the plot data
# PlotlyJS.restyle!(plt.o, i, plotly_series(d))
PlotlyJS.restyle!(plt.o, i, Dict(:x=>(d[:x],), :y=>(d[:y],)))
plt
end
@@ -105,8 +114,11 @@ end
# ----------------------------------------------------------------
function Base.writemime(io::IO, m::MIME"text/html", plt::PlottingObject{PlotlyJSPackage})
Base.writemime(io, m, plt.o)
end
function Base.display(::PlotsDisplay, plt::Plot{PlotlyJSPackage})
dump(plt.o)
display(plt.o)
end
+129 -30
View File
@@ -31,6 +31,7 @@ end
# convert colorant to 4-tuple RGBA
getPyPlotColor(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (red, green, blue, alpha))
getPyPlotColor(cvec::ColorVector, α=nothing) = map(getPyPlotColor, convertColor(cvec, α).v)
getPyPlotColor(scheme::ColorScheme, α=nothing) = getPyPlotColor(convertColor(getColor(scheme), α))
getPyPlotColor(c, α=nothing) = getPyPlotColor(convertColor(c, α))
# getPyPlotColor(c, alpha) = getPyPlotColor(colorscheme(c, alpha))
@@ -44,8 +45,8 @@ function getPyPlotColorMap(c::ColorGradient, α=nothing)
pycolors.pymember("LinearSegmentedColormap")[:from_list]("tmp", pyvals)
end
# anything else just gets a redsblue gradient
getPyPlotColorMap(c, α=nothing) = getPyPlotColorMap(ColorGradient(:redsblues), α)
# anything else just gets a bluesred gradient
getPyPlotColorMap(c, α=nothing) = getPyPlotColorMap(ColorGradient(:bluesreds), α)
# get the style (solid, dashed, etc)
function getPyPlotLineStyle(linetype::Symbol, linestyle::Symbol)
@@ -90,8 +91,14 @@ function getPyPlotMarker(marker::Symbol)
return "o"
end
# getPyPlotMarker(markers::AVec) = map(getPyPlotMarker, markers)
function getPyPlotMarker(markers::AVec)
warn("Vectors of markers are currently unsupported in PyPlot: $markers")
getPyPlotMarker(markers[1])
end
# pass through
function getPyPlotMarker(marker::@compat(AbstractString))
function getPyPlotMarker(marker::AbstractString)
@assert length(marker) == 1
marker
end
@@ -216,6 +223,41 @@ end
# ------------------------------------------------------------------
function pyplot_figure(plotargs::Dict)
w,h = map(px2inch, plotargs[:size])
bgcolor = getPyPlotColor(plotargs[:background_color])
# reuse the current figure?
fig = if plotargs[:overwrite_figure]
PyPlot.gcf()
else
PyPlot.figure()
end
# update the specs
# fig[:set_size_inches](w,h, (isijulia() ? [] : [true])...)
fig[:set_size_inches](w, h, forward = true)
fig[:set_facecolor](bgcolor)
fig[:set_dpi](DPI)
fig[:set_tight_layout](true)
# clear the figure
PyPlot.clf()
# resize the window
PyPlot.plt[:get_current_fig_manager]()[:resize](plotargs[:size]...)
fig
end
function pyplot_3d_setup!(wrap, d)
# 3D?
# if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
if trueOrAllTrue(lt -> lt in _3dTypes, get(d, :linetype, :none))
push!(wrap.kwargs, (:projection, "3d"))
end
end
# TODO:
# fillto # might have to use barHack/histogramHack??
# reg # true or false, add a regression line for each line
@@ -232,13 +274,13 @@ function _create_plot(pkg::PyPlotPackage; kw...)
if haskey(d, :subplot)
wrap = nothing
else
w,h = map(px2inch, d[:size])
bgcolor = getPyPlotColor(d[:background_color])
wrap = PyPlotAxisWrapper(nothing, nothing, PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = DPI, tight_layout = true), [])
wrap = PyPlotAxisWrapper(nothing, nothing, pyplot_figure(d), [])
# wrap = PyPlotAxisWrapper(nothing, nothing, PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = DPI, tight_layout = true), [])
if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
push!(wrap.kwargs, (:projection, "3d"))
end
# if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
# push!(wrap.kwargs, (:projection, "3d"))
# end
pyplot_3d_setup!(wrap, d)
end
plt = Plot(wrap, pkg, 0, d, Dict[])
@@ -249,11 +291,21 @@ end
function _add_series(pkg::PyPlotPackage, plt::Plot; kw...)
d = Dict(kw)
# 3D plots have a different underlying Axes object in PyPlot
lt = d[:linetype]
if lt in _3dTypes && isempty(plt.o.kwargs)
push!(plt.o.kwargs, (:projection, "3d"))
end
# handle mismatched x/y sizes, as PyPlot doesn't like that
x, y = d[:x], d[:y]
nx, ny = map(length, (x,y))
if nx < ny
d[:x] = Float64[x[mod1(i,nx)] for i=1:ny]
else
d[:y] = Float64[y[mod1(i,ny)] for i=1:nx]
end
ax = getAxis(plt, d[:axis])
if !(lt in supportedTypes(pkg))
error("linetype $(lt) is unsupported in PyPlot. Choose from: $(supportedTypes(pkg))")
@@ -333,11 +385,21 @@ function _add_series(pkg::PyPlotPackage, plt::Plot; kw...)
extra_kwargs[:c] = convert(Vector{Float64}, d[:zcolor])
extra_kwargs[:cmap] = getPyPlotColorMap(c, d[:markeralpha])
else
extra_kwargs[:c] = getPyPlotColor(c, d[:markeralpha])
end
if d[:markeralpha] != nothing
extra_kwargs[:alpha] = d[:markeralpha]
# extra_kwargs[:c] = getPyPlotColor(c, d[:markeralpha])
ppc = getPyPlotColor(c, d[:markeralpha])
# total hack due to PyPlot bug (see issue #145).
# hack: duplicate the color vector when the total rgba fields is the same as the series length
if (typeof(ppc) <: AbstractArray && length(ppc)*4 == length(x)) ||
(typeof(ppc) <: Tuple && length(x) == 4)
ppc = vcat(ppc, ppc)
end
extra_kwargs[:c] = ppc
end
# if d[:markeralpha] != nothing
# extra_kwargs[:alpha] = d[:markeralpha]
# end
extra_kwargs[:edgecolors] = getPyPlotColor(d[:markerstrokecolor], d[:markerstrokealpha])
extra_kwargs[:linewidths] = d[:markerstrokewidth]
else
@@ -444,25 +506,50 @@ function Base.getindex(plt::Plot{PyPlotPackage}, i::Integer)
end
end
function minmaxseries(ds, vec, axis)
lo, hi = Inf, -Inf
for d in ds
d[:axis] == axis || continue
v = d[vec]
if length(v) > 0
vlo, vhi = extrema(v)
lo = min(lo, vlo)
hi = max(hi, vhi)
end
end
if lo == hi
hi = if lo == 0
1e-6
else
hi + min(abs(1e-2hi), 1e-6)
end
end
lo, hi
end
# TODO: this needs to handle one-sided fixed limits
function set_lims!(plt::Plot{PyPlotPackage}, axis::Symbol)
ax = getAxis(plt, axis)
if plt.plotargs[:xlims] == :auto
ax[:set_xlim](minmaxseries(plt.seriesargs, :x, axis)...)
end
if plt.plotargs[:ylims] == :auto
ax[:set_ylim](minmaxseries(plt.seriesargs, :y, axis)...)
end
end
function Base.setindex!{X,Y}(plt::Plot{PyPlotPackage}, xy::Tuple{X,Y}, i::Integer)
series = plt.seriesargs[i][:serieshandle]
d = plt.seriesargs[i]
series = d[:serieshandle]
x, y = xy
d[:x], d[:y] = x, y
try
series[:set_data](x, y)
catch
series[:set_offsets](hcat(x, y))
end
ax = series[:axes]
if plt.plotargs[:xlims] == :auto
xmin, xmax = ax[:get_xlim]()
ax[:set_xlim](min(xmin, minimum(x)), max(xmax, maximum(x)))
end
if plt.plotargs[:ylims] == :auto
ymin, ymax = ax[:get_ylim]()
ax[:set_ylim](min(ymin, minimum(y)), max(ymax, maximum(y)))
end
set_lims!(plt, d[:axis])
plt
end
@@ -477,7 +564,13 @@ function addPyPlotLims(ax, lims, isx::Bool)
lims == :auto && return
ltype = limsType(lims)
if ltype == :limits
ax[isx ? :set_xlim : :set_ylim](lims...)
if isx
isfinite(lims[1]) && ax[:set_xlim](left = lims[1])
isfinite(lims[2]) && ax[:set_xlim](right = lims[2])
else
isfinite(lims[1]) && ax[:set_ylim](bottom = lims[1])
isfinite(lims[2]) && ax[:set_ylim](top = lims[2])
end
else
error("Invalid input for $(isx ? "xlims" : "ylims"): ", lims)
end
@@ -493,7 +586,8 @@ function addPyPlotTicks(ax, ticks, isx::Bool)
if ttype == :ticks
ax[isx ? :set_xticks : :set_yticks](ticks)
elseif ttype == :ticks_and_labels
ax[isx ? :set_xticks : :set_yticks](ticks...)
ax[isx ? :set_xticks : :set_yticks](ticks[1])
ax[isx ? :set_xticklabels : :set_yticklabels](ticks[2])
else
error("Invalid input for $(isx ? "xticks" : "yticks"): ", ticks)
end
@@ -611,9 +705,11 @@ end
function _create_subplot(subplt::Subplot{PyPlotPackage}, isbefore::Bool)
l = subplt.layout
w,h = map(px2inch, getplotargs(subplt,1)[:size])
bgcolor = getPyPlotColor(getplotargs(subplt,1)[:background_color])
fig = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = DPI, tight_layout = true)
# w,h = map(px2inch, getplotargs(subplt,1)[:size])
# bgcolor = getPyPlotColor(getplotargs(subplt,1)[:background_color])
# fig = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = DPI, tight_layout = true)
plotargs = getplotargs(subplt, 1)
fig = pyplot_figure(plotargs)
nr = nrows(l)
for (i,(r,c)) in enumerate(l)
@@ -624,10 +720,12 @@ function _create_subplot(subplt::Subplot{PyPlotPackage}, isbefore::Bool)
ax = fig[:add_subplot](nr, nc, fakeidx)
subplt.plts[i].o = PyPlotAxisWrapper(ax, nothing, fig, [])
pyplot_3d_setup!(subplt.plts[i].o, plotargs)
end
# subplt.o = PyPlotFigWrapper(fig, [])
subplt.o = PyPlotAxisWrapper(nothing, nothing, fig, [])
pyplot_3d_setup!(subplt.o, plotargs)
true
end
@@ -771,7 +869,7 @@ const _pyplot_mimeformats = @compat Dict(
"application/pdf" => "pdf",
"image/png" => "png",
"application/postscript" => "ps",
# "image/svg+xml" => "svg"
"image/svg+xml" => "svg"
)
@@ -790,6 +888,7 @@ for (mime, fmt) in _pyplot_mimeformats
end
end
# function Base.writemime(io::IO, m::MIME"image/png", subplt::Subplot{PyPlotPackage})
# finalizePlot(subplt)
# writemime(io, m, getfig(subplt.o))
+1
View File
@@ -3,6 +3,7 @@
function _initialize_backend(::QwtPackage; kw...)
@eval begin
warn("Qwt is no longer supported... many features will likely be broken.")
import Qwt
export Qwt
end
+7 -3
View File
@@ -44,6 +44,7 @@ supportedArgs(::GadflyPackage) = [
:markeralpha,
:markerstrokewidth,
:markerstrokecolor,
:markerstrokealpha,
# :markerstrokestyle,
:n,
:nbins,
@@ -124,6 +125,7 @@ supportedArgs(::PyPlotPackage) = [
:markersize,
:markerstrokewidth,
:markerstrokecolor,
:markerstrokealpha,
# :markerstrokestyle,
:n,
:nbins,
@@ -160,6 +162,7 @@ supportedArgs(::PyPlotPackage) = [
:fillalpha,
:linealpha,
:markeralpha,
:overwrite_figure,
]
supportedAxes(::PyPlotPackage) = _allAxes
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :steppre, :steppost, #:sticks,
@@ -189,6 +192,7 @@ supportedArgs(::GRPackage) = [
:label,
:layout,
:legend,
:colorbar,
:linestyle,
:linetype,
:linewidth,
@@ -239,8 +243,8 @@ supportedTypes(::GRPackage) = [:none, :line, :path, :steppre, :steppost, :sticks
:scatter, :heatmap, :hexbin, :hist, :density, :bar,
:hline, :vline, :contour, :path3d, :scatter3d, :surface,
:wireframe, :ohlc, :pie]
supportedStyles(::GRPackage) = [:auto, :solid, :dash, :dot, :dashdot]
supportedMarkers(::GRPackage) = vcat([:none, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :pentagon, :hexagon, :cross, :xcross, :star5], Shape)
supportedStyles(::GRPackage) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
supportedMarkers(::GRPackage) = vcat(_allMarkers, Shape)
supportedScales(::GRPackage) = [:identity, :log10]
subplotSupported(::GRPackage) = true
@@ -359,7 +363,7 @@ supportedArgs(::UnicodePlotsPackage) = [
# :z,
]
supportedAxes(::UnicodePlotsPackage) = [:auto, :left]
supportedTypes(::UnicodePlotsPackage) = [:none, :line, :path, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
supportedTypes(::UnicodePlotsPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
supportedStyles(::UnicodePlotsPackage) = [:auto, :solid]
supportedMarkers(::UnicodePlotsPackage) = [:none, :auto, :ellipse]
supportedScales(::UnicodePlotsPackage) = [:identity]
+2 -1
View File
@@ -5,7 +5,8 @@
function _initialize_backend(::WinstonPackage; kw...)
@eval begin
ENV["WINSTON_OUTPUT"] = "gtk"
# ENV["WINSTON_OUTPUT"] = "gtk"
warn("Winston is no longer supported... many features will likely be broken.")
import Winston, Gtk
export Winston, Gtk
end
+86 -3
View File
@@ -131,6 +131,7 @@ immutable PlotText
str::@compat(AbstractString)
font::Font
end
PlotText(str) = PlotText(string(str), font())
function text(str, args...)
PlotText(string(str), font(args...))
@@ -157,7 +158,8 @@ function stroke(args...; alpha = nothing)
for arg in args
T = typeof(arg)
if arg in _allStyles
# if arg in _allStyles
if allStyles(arg)
style = arg
elseif T <: Colorant
color = arg
@@ -165,7 +167,11 @@ function stroke(args...; alpha = nothing)
try
color = parse(Colorant, string(arg))
end
elseif typeof(arg) <: Real
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
elseif allAlphas(arg)
alpha = arg
# elseif typeof(arg) <: Real
elseif allReals(arg)
width = arg
else
warn("Unused stroke arg: $arg ($(typeof(arg)))")
@@ -198,7 +204,11 @@ function brush(args...; alpha = nothing)
try
color = parse(Colorant, string(arg))
end
elseif typeof(arg) <: Real
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
elseif allAlphas(arg)
alpha = arg
# elseif typeof(arg) <: Real
elseif allReals(arg)
size = arg
else
warn("Unused brush arg: $arg ($(typeof(arg)))")
@@ -233,6 +243,11 @@ Surface(f::Function, x, y) = Surface(Float64[f(xi,yi) for xi in x, yi in y])
Base.Array(surf::Surface) = surf.surf
for f in (:length, :size)
@eval Base.$f(surf::Surface, args...) = $f(surf.surf, args...)
end
Base.copy(surf::Surface) = Surface(copy(surf.surf))
# -----------------------------------------------------------------------
type OHLC{T<:Real}
@@ -241,3 +256,71 @@ type OHLC{T<:Real}
low::T
close::T
end
# @require FixedSizeArrays begin
export
P2,
P3,
BezierCurve,
curve_points,
directed_curve
typealias P2 FixedSizeArrays.Vec{2,Float64}
typealias P3 FixedSizeArrays.Vec{3,Float64}
type BezierCurve{T <: FixedSizeArrays.Vec}
control_points::Vector{T}
end
function Base.call(bc::BezierCurve, t::Real)
p = zero(P2)
n = length(bc.control_points)-1
for i in 0:n
p += bc.control_points[i+1] * binomial(n, i) * (1-t)^(n-i) * t^i
end
p
end
Base.mean(x::Real, y::Real) = 0.5*(x+y)
Base.mean{N,T<:Real}(ps::FixedSizeArrays.Vec{N,T}...) = sum(ps) / length(ps)
curve_points(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, linspace(range..., n))
# build a BezierCurve which leaves point p vertically upwards and arrives point q vertically upwards.
# may create a loop if necessary. Assumes the view is [0,1]
function directed_curve(p::P2, q::P2; xview = 0:1, yview = 0:1)
mn = mean(p, q)
diff = q - p
minx, maxx = minimum(xview), maximum(xview)
miny, maxy = minimum(yview), maximum(yview)
diffpct = P2(diff[1] / (maxx - minx),
diff[2] / (maxy - miny))
# these points give the initial/final "rise"
# vertical_offset = P2(0, (maxy - miny) * max(0.03, min(abs(0.5diffpct[2]), 1.0)))
vertical_offset = P2(0, max(0.15, 0.5norm(diff)))
upper_control = p + vertical_offset
lower_control = q - vertical_offset
# try to figure out when to loop around vs just connecting straight
# TODO: choose loop direction based on sign of p[1]??
# x_close_together = abs(diffpct[1]) <= 0.05
p_is_higher = diff[2] <= 0
inside_control_points = if p_is_higher
# add curve points which will create a loop
sgn = mn[1] < 0.5 * (maxx + minx) ? -1 : 1
inside_offset = P2(0.3 * (maxx - minx), 0)
additional_offset = P2(sgn * diff[1], 0) # make it even loopier
[upper_control + sgn * (inside_offset + max(0, additional_offset)),
lower_control + sgn * (inside_offset + max(0, -additional_offset))]
else
[]
end
BezierCurve([p, upper_control, inside_control_points..., lower_control, q])
end
# end
+5
View File
@@ -112,3 +112,8 @@ gui(plt::PlottingObject = current()) = display(PlotsDisplay(), plt)
# override the REPL display to open a gui window
Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::PlottingObject) = gui(plt)
# a backup for html... passes to svg
function Base.writemime(io::IO, ::MIME"text/html", plt::PlottingObject)
writemime(io, MIME("image/svg+xml"), plt)
end
+65 -26
View File
@@ -187,6 +187,7 @@ annotations(::@compat(Void)) = []
annotations{X,Y,V}(v::AVec{@compat(Tuple{X,Y,V})}) = v
annotations{X,Y,V}(t::@compat(Tuple{X,Y,V})) = [t]
annotations(v::AVec{PlotText}) = v
annotations(v::AVec) = map(PlotText, v)
annotations(anns) = error("Expecting a tuple (or vector of tuples) for annotations: ",
"(x, y, annotation)\n got: $(typeof(anns))")
@@ -227,41 +228,50 @@ end
typealias FuncOrFuncs @compat(Union{Function, AVec{Function}})
all3D(d::Dict) = trueOrAllTrue(lt -> lt in (:contour, :surface, :wireframe, :image), get(d, :linetype, :none))
# missing
convertToAnyVector(v::@compat(Void); kw...) = Any[nothing], nothing
convertToAnyVector(v::@compat(Void), d::Dict) = Any[nothing], nothing
# fixed number of blank series
convertToAnyVector(n::Integer; kw...) = Any[zeros(0) for i in 1:n], nothing
convertToAnyVector(n::Integer, d::Dict) = Any[zeros(0) for i in 1:n], nothing
# numeric vector
convertToAnyVector{T<:Real}(v::AVec{T}; kw...) = Any[v], nothing
convertToAnyVector{T<:Real}(v::AVec{T}, d::Dict) = Any[v], nothing
# string vector
convertToAnyVector{T<:@compat(AbstractString)}(v::AVec{T}; kw...) = Any[v], nothing
convertToAnyVector{T<:@compat(AbstractString)}(v::AVec{T}, d::Dict) = Any[v], nothing
# numeric matrix
convertToAnyVector{T<:Real}(v::AMat{T}; kw...) = Any[v[:,i] for i in 1:size(v,2)], nothing
function convertToAnyVector{T<:Real}(v::AMat{T}, d::Dict)
if all3D(d)
Any[Surface(v)]
else
Any[v[:,i] for i in 1:size(v,2)]
end, nothing
end
# function
convertToAnyVector(f::Function; kw...) = Any[f], nothing
convertToAnyVector(f::Function, d::Dict) = Any[f], nothing
# surface
convertToAnyVector(s::Surface; kw...) = Any[s], nothing
convertToAnyVector(s::Surface, d::Dict) = Any[s], nothing
# vector of OHLC
convertToAnyVector(v::AVec{OHLC}; kw...) = Any[v], nothing
convertToAnyVector(v::AVec{OHLC}, d::Dict) = Any[v], nothing
# dates
convertToAnyVector{D<:Union{Date,DateTime}}(dts::AVec{D}; kw...) = Any[dts], nothing
convertToAnyVector{D<:Union{Date,DateTime}}(dts::AVec{D}, d::Dict) = Any[dts], nothing
# list of things (maybe other vectors, functions, or something else)
function convertToAnyVector(v::AVec; kw...)
function convertToAnyVector(v::AVec, d::Dict)
if all(x -> typeof(x) <: Real, v)
# all real numbers wrap the whole vector as one item
Any[convert(Vector{Float64}, v)], nothing
else
# something else... treat each element as an item
Any[vi for vi in v], nothing
vcat(Any[convertToAnyVector(vi, d)[1] for vi in v]...), nothing
# Any[vi for vi in v], nothing
end
end
@@ -270,7 +280,7 @@ end
# in computeXandY, we take in any of the possible items, convert into proper x/y vectors, then return.
# this is also where all the "set x to 1:length(y)" happens, and also where we assert on lengths.
computeX(x::@compat(Void), y) = 1:length(y)
computeX(x::@compat(Void), y) = 1:size(y,1)
computeX(x, y) = copy(x)
computeY(x, y::Function) = map(y, x)
computeY(x, y) = copy(y)
@@ -289,8 +299,9 @@ end
# create n=max(mx,my) series arguments. the shorter list is cycled through
# note: everything should flow through this
function createKWargsList(plt::PlottingObject, x, y; kw...)
xs, xmeta = convertToAnyVector(x; kw...)
ys, ymeta = convertToAnyVector(y; kw...)
kwdict = Dict(kw)
xs, xmeta = convertToAnyVector(x, kwdict)
ys, ymeta = convertToAnyVector(y, kwdict)
mx = length(xs)
my = length(ys)
@@ -298,7 +309,7 @@ function createKWargsList(plt::PlottingObject, x, y; kw...)
for i in 1:max(mx, my)
# try to set labels using ymeta
d = Dict(kw)
d = copy(kwdict)
if !haskey(d, :label) && ymeta != nothing
if isa(ymeta, Symbol)
d[:label] = string(ymeta)
@@ -315,13 +326,22 @@ function createKWargsList(plt::PlottingObject, x, y; kw...)
dumpdict(d, "after getSeriesArgs")
d[:x], d[:y] = computeXandY(xs[mod1(i,mx)], ys[mod1(i,my)])
lt = d[:linetype]
if isa(d[:y], Surface)
if lt in (:contour, :surface, :wireframe, :image)
z = d[:y]
d[:y] = 1:size(z,2)
d[lt == :image ? :zcolor : :z] = z
end
end
if haskey(d, :idxfilter)
d[:x] = d[:x][d[:idxfilter]]
d[:y] = d[:y][d[:idxfilter]]
end
# for linetype `line`, need to sort by x values
if d[:linetype] == :line
if lt == :line
# order by x
indices = sortperm(d[:x])
d[:x] = d[:x][indices]
@@ -377,6 +397,16 @@ function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, zvec::AVec; kw.
createKWargsList(plt, x, y; z=zvec, d...)
end
function createKWargsList{T<:Real}(plt::PlottingObject, z::AMat{T}; kw...)
d = Dict(kw)
if all3D(d)
n,m = size(z)
createKWargsList(plt, 1:n, 1:m, z; kw...)
else
createKWargsList(plt, nothing, z; kw...)
end
end
# contours or surfaces... function grid
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec, zf::Function; kw...)
# only allow sorted x/y for now
@@ -453,6 +483,11 @@ createKWargsList{T<:Real}(plt::PlottingObject, fx::FuncOrFuncs, fy::FuncOrFuncs,
createKWargsList{T<:Real}(plt::PlottingObject, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs; kw...) = createKWargsList(plt, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u); kw...)
createKWargsList(plt::PlottingObject, fx::FuncOrFuncs, fy::FuncOrFuncs, umin::Real, umax::Real, numPoints::Int = 1000; kw...) = createKWargsList(plt, fx, fy, linspace(umin, umax, numPoints); kw...)
# special handling... 3D parametric function(s)
createKWargsList{T<:Real}(plt::PlottingObject, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, u::AVec{T}; kw...) = createKWargsList(plt, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u); kw...)
createKWargsList{T<:Real}(plt::PlottingObject, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs; kw...) = createKWargsList(plt, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u); kw...)
createKWargsList(plt::PlottingObject, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, umin::Real, umax::Real, numPoints::Int = 1000; kw...) = createKWargsList(plt, fx, fy, fz, linspace(umin, umax, numPoints); kw...)
# (x,y) tuples
function createKWargsList{R1<:Real,R2<:Real}(plt::PlottingObject, xy::AVec{Tuple{R1,R2}}; kw...)
createKWargsList(plt, unzip(xy)...; kw...)
@@ -482,7 +517,7 @@ end
# --------------------------------------------------------------------
@require FixedSizeArrays begin
# @require FixedSizeArrays begin
unzip{T}(x::AVec{FixedSizeArrays.Vec{2,T}}) = T[xi[1] for xi in x], T[xi[2] for xi in x]
unzip{T}(x::FixedSizeArrays.Vec{2,T}) = T[x[1]], T[x[2]]
@@ -495,7 +530,7 @@ end
createKWargsList(plt, [xy[1]], [xy[2]]; kw...)
end
end
# end
# --------------------------------------------------------------------
@@ -516,18 +551,22 @@ end
end
end
function getDataFrameFromKW(; kw...)
for (k,v) in kw
if k == :dataframe
return v
end
function getDataFrameFromKW(d::Dict)
# for (k,v) in kw
# if k == :dataframe
# return v
# end
# end
get(d, :dataframe) do
error("Missing dataframe argument!")
end
error("Missing dataframe argument in arguments!")
end
# the conversion functions for when we pass symbols or vectors of symbols to reference dataframes
convertToAnyVector(s::Symbol; kw...) = Any[getDataFrameFromKW(;kw...)[s]], s
convertToAnyVector(v::AVec{Symbol}; kw...) = (df = getDataFrameFromKW(;kw...); Any[df[s] for s in v]), v
# convertToAnyVector(s::Symbol; kw...) = Any[getDataFrameFromKW(;kw...)[s]], s
# convertToAnyVector(v::AVec{Symbol}; kw...) = (df = getDataFrameFromKW(;kw...); Any[df[s] for s in v]), v
convertToAnyVector(s::Symbol, d::Dict) = Any[getDataFrameFromKW(d)[s]], s
convertToAnyVector(v::AVec{Symbol}, d::Dict) = (df = getDataFrameFromKW(d); Any[df[s] for s in v]), v
end
+19
View File
@@ -206,6 +206,7 @@ isscalar(::Any) = false
# ticksType{T<:Real,S<:Real}(ticks::@compat(Tuple{T,S})) = :limits
ticksType{T<:Real}(ticks::AVec{T}) = :ticks
ticksType{T<:AbstractString}(ticks::AVec{T}) = :labels
ticksType{T<:AVec,S<:AVec}(ticks::@compat(Tuple{T,S})) = :ticks_and_labels
ticksType(ticks) = :invalid
@@ -221,6 +222,24 @@ Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
# ---------------------------------------------------------------
wraptuple(x::@compat(Tuple)) = x
wraptuple(x) = (x,)
trueOrAllTrue(f::Function, x::AbstractArray) = all(f, x)
trueOrAllTrue(f::Function, x) = f(x)
allLineTypes(arg) = trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
allStyles(arg) = trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
allShapes(arg) = trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg) ||
trueOrAllTrue(a -> isa(a, Shape), arg)
allAlphas(arg) = trueOrAllTrue(a -> (typeof(a) <: Real && a > 0 && a < 1) ||
(typeof(a) <: AbstractFloat && (a == zero(typeof(a)) || a == one(typeof(a)))), arg)
allReals(arg) = trueOrAllTrue(a -> typeof(a) <: Real, arg)
allFunctions(arg) = trueOrAllTrue(a -> isa(a, Function), arg)
# ---------------------------------------------------------------
"""
Allows temporary setting of backend and defaults for Plots. Settings apply only for the `do` block. Example:
```
+1
View File
@@ -9,3 +9,4 @@ Images
ImageMagick
PyPlot
@osx QuartzImageIO
GR
+12 -4
View File
@@ -31,14 +31,15 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is
# ensure consistent results
srand(1234)
# reference image directory setup
refdir = joinpath(Pkg.dir("ExamplePlots"), "test", "refimg", string(pkg))
# test function
func = (fn, idx) -> begin
map(eval, example.exprs)
png(fn)
end
# reference image directory setup
refdir = joinpath(Pkg.dir("ExamplePlots"), "test", "refimg", string(pkg))
try
run(`mkdir -p $refdir`)
catch err
@@ -51,9 +52,16 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is
test_images(vtest, popup=popup, sigma=sigma, eps=eps)
end
function image_comparison_facts(pkg::Symbol; skip = [], debug = false, sigma = [1,1], eps = 1e-2)
function image_comparison_facts(pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1,1], # number of pixels to "blur"
eps = 1e-2) # acceptable error (percent)
for i in 1:length(ExamplePlots._examples)
i in skip && continue
@fact image_comparison_tests(pkg, i, debug=debug, sigma=sigma, eps=eps) |> success --> true
if only == nothing || i in only
@fact image_comparison_tests(pkg, i, debug=debug, sigma=sigma, eps=eps) |> success --> true
end
end
end
+8 -1
View File
@@ -23,7 +23,14 @@ facts("PyPlot") do
@fact pyplot() --> Plots.PyPlotPackage()
@fact backend() --> Plots.PyPlotPackage()
image_comparison_facts(:pyplot, skip=[10,19,21,23], eps=img_eps)
image_comparison_facts(:pyplot, skip=[4,10,13,19,21,23], eps=img_eps)
end
facts("GR") do
@fact gr() --> Plots.GRPackage()
@fact backend() --> Plots.GRPackage()
# image_comparison_facts(:gr, only=[1], eps=img_eps)
end
FactCheck.exitstatus()