Compare commits

...

39 Commits

Author SHA1 Message Date
Thomas Breloff de6e3d46ec appveyor fix 2016-06-27 21:49:45 -04:00
Thomas Breloff 3006a26500 revert precompile; add appveyor; gr fixes for markersize, shapes, and legend entries; add GR to tests again; recipe fixes and cleanup 2016-06-27 21:43:57 -04:00
Thomas Breloff 6ffed9387c snoop and precompile; bumped version 2016-06-27 16:52:50 -04:00
Thomas Breloff 558627e7a9 NEWS 2016-06-27 14:02:01 -04:00
Thomas Breloff 4b276f977c revert pyplot heatmap change 2016-06-27 12:25:45 -04:00
Thomas Breloff 99fe4f615d show arg fix; add image to all3D 2016-06-27 12:09:08 -04:00
Thomas Breloff 928c306803 dpi fixes 2016-06-27 10:06:40 -04:00
Thomas Breloff a3eddf8ba7 dpi support for pyplot 2016-06-27 09:20:42 -04:00
Thomas Breloff 78e0ae31af removed chorddiagram 2016-06-26 12:37:06 -04:00
Thomas Breloff 1a90ce0950 recoded boxplot recipe to match violin approach; switched marker to line/fill for shape seriestype: ref #347 2016-06-26 11:36:09 -04:00
Thomas Breloff 2465b3eb5a fallback warnings for missing _writemime and _display 2016-06-26 11:08:06 -04:00
Thomas Breloff 16a2e34e95 writemime fix for Interact; working on glvisualize 2016-06-26 10:34:34 -04:00
Thomas Breloff 5c52d68091 working on glvisualize 2016-06-25 18:06:27 -04:00
Thomas Breloff 1a2e180f4f working on glvisualize 2016-06-25 17:00:45 -04:00
Thomas Breloff 9048053669 working on glvisualize 2016-06-25 10:56:51 -04:00
Thomas Breloff 69b69714cb working on glvisualize 2016-06-24 12:15:21 -04:00
Thomas Breloff 1ecd9f9e19 working on glvisualize 2016-06-24 11:52:33 -04:00
Thomas Breloff 2bca9ca9ec square link 2016-06-24 11:00:28 -04:00
Thomas Breloff d66028ed0d glvisualize: support for path/path3d with or without markers, 3d markers are spheres 2016-06-23 17:00:08 -04:00
Thomas Breloff 1cf33044bc scatter and scatter3d support in glvisualize 2016-06-23 14:59:04 -04:00
Thomas Breloff 2c138c8355 readme 2016-06-22 13:22:25 -04:00
Thomas Breloff 73ffcb9bc1 changed convertToAnyVector AMat so that all matrices use the version previously for numbers; violin cleanup 2016-06-22 13:20:09 -04:00
Thomas Breloff 730025e144 recoded violin; removed try/catch around apply_recipe; default values for xtick/ytick in GR 2016-06-22 11:45:30 -04:00
Thomas Breloff 91aa1d718a animations: use tmp.gif for ijulia, remove prefix from convert call; closes #346 2016-06-22 11:01:00 -04:00
Thomas Breloff f881bfc4fc add Segments; pyplot: switch bar/hist/hist2d to recipes and path fix; change bar to shape; removed GR from tests 2016-06-20 23:11:23 -04:00
Thomas Breloff e76c3fff69 refactored gr markers fixing bugs and enabling features; clear subplot/axis args from d in _plot 2016-06-20 19:51:03 -04:00
Thomas Breloff 9f168071ff subplot attributes fixes 2016-06-20 15:11:25 -04:00
Thomas Breloff b6652b7619 improvements to bbox construction and inset subplots 2016-06-20 10:13:03 -04:00
Thomas Breloff f6d501f69e plot recipe fixes 2016-06-20 00:11:06 -04:00
Thomas Breloff 4c052cb3b3 colors cgrad and getindex 2016-06-19 11:25:25 -04:00
Thomas Breloff ea8ccf38db plot recipe fixes 2016-06-18 22:30:47 -04:00
Thomas Breloff cf12ff8070 plot logic cleanup; added plot recipes 2016-06-18 09:33:34 -04:00
Thomas Breloff b7a95244db handle seriestype aliases; handle vector of seriestypes; hvline_limits; added cycle for InputWrapper; turn on GR tests for OSX 2016-06-18 00:14:20 -04:00
Tom Breloff 4c884651a8 Merge pull request #343 from jheinen/dev
Added suport for marker borders
2016-06-18 00:02:42 -04:00
Thomas Breloff e9eca577aa plotlyjs supported_scales; violin check 2016-06-17 15:31:01 -04:00
Josef Heinen cff78b477c Added suport for marker borders 2016-06-17 20:21:07 +02:00
Tom Breloff b232410d25 Merge pull request #338 from jheinen/dev
use temporary files when generating MIME files
2016-06-17 08:09:53 -04:00
Josef Heinen 5ff338d4ac use temporary files when generating MIME files 2016-06-17 09:34:10 +02:00
Thomas Breloff a5ceea153d bump plots version 0.7.3 2016-06-16 21:00:25 -04:00
25 changed files with 1305 additions and 1076 deletions
+24
View File
@@ -9,6 +9,30 @@
## 0.7 (current master/dev)
#### 0.7.3
- rebuild violin and boxplot recipes
- "plot recipes"
- `cgrad` method for easy color gradient creation
- improvements to inset subplots
- Segments and iter_segments for NaN-separated vectors
- `bar` recipe now creates a `shape` series
- writemime fix for Interact.jl
- `link = :square` option
- !!! set `shape` attributes with line/fill, NOT marker/markerstroke !!!
- basic DPI support
- moved chorddiagram to PlotRecipes
- GR:
- use temp files for img output
- basic support for marker strokes and other marker fixes
- PyPlot:
- Switch to recipes for bar, histogram, histogram2d
- GLVisualize
- subplots
- path/scatter and path3d/scatter3d
- initial drawing of axes
- many smaller fixes and improvements
#### 0.7.2
- line_z arg for multicolored line segments
-2
View File
@@ -22,8 +22,6 @@ Use the [preprocessing pipeline](http://plots.readthedocs.io/en/latest/pipeline/
```julia
using Plots
pyplot(reuse=true)
@gif for i in linspace(0,2π,100)
X = Y = linspace(-5,5,40)
surface(X, Y, (x,y) -> sin(x+10sin(i))+cos(y))
+10 -15
View File
@@ -1,14 +1,11 @@
environment:
matrix:
- JULIAVERSION: "julialang/bin/winnt/x86/0.3/julia-0.3-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.3/julia-0.3-latest-win64.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe"
branches:
only:
- master
- /release-.*/
# Releases
- JULIAVERSION: "stable/win32"
- JULIAVERSION: "stable/win64"
# Nightlies
- JULIAVERSION: "download/win32"
- JULIAVERSION: "download/win64"
notifications:
- provider: Email
@@ -18,17 +15,15 @@ notifications:
install:
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$("http://s3.amazonaws.com/"+$env:JULIAVERSION),
"C:\projects\julia-binary.exe")
- ps: (new-object net.webclient).DownloadFile($("http://status.julialang.org/"+$env:JULIAVERSION), "C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"Plots\"); Pkg.build(\"Plots\")"
- C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"Plots\"); Pkg.build(\"Plots\")"
test_script:
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"Plots\")"
# - C:\projects\julia\bin\julia -e "Pkg.test(\"Plots\")"
- C:\projects\julia\bin\julia -e "include(Pkg.dir(\"Plots\", \"test\", \"travis_commands.jl\"))"
+10 -4
View File
@@ -1,5 +1,5 @@
__precompile__()
__precompile__()
module Plots
@@ -10,6 +10,7 @@ using Reexport
using FixedSizeArrays
@reexport using RecipesBase
using Base.Meta
# using PlotUtils
export
AbstractPlot,
@@ -78,6 +79,7 @@ export
Surface,
OHLC,
arrow,
Segments,
colorscheme,
ColorScheme,
@@ -103,10 +105,7 @@ export
@animate,
@gif,
PlotRecipe,
spy,
arcdiagram,
chorddiagram,
test_examples,
iter_segments,
@@ -255,4 +254,11 @@ end
# ---------------------------------------------------------
# if VERSION >= v"0.4.0-dev+5512"
# include("precompile.jl")
# _precompile_()
# end
# ---------------------------------------------------------
end # module
+4 -4
View File
@@ -24,7 +24,7 @@ immutable AnimatedGif
filename::Compat.ASCIIString
end
function gif(anim::Animation, fn = tempname()*".gif"; fps::Integer = 20)
function gif(anim::Animation, fn = (isijulia() ? "tmp.gif" : tempname()*".gif"); fps::Integer = 20)
fn = abspath(fn)
try
@@ -35,8 +35,8 @@ function gif(anim::Animation, fn = tempname()*".gif"; fps::Integer = 20)
if isfile(file) && !haskey(ENV, "MAGICK_CONFIGURE_PATH")
include(file)
end
prefix = get(ENV, "MAGICK_CONFIGURE_PATH", "")
run(`$(joinpath(prefix, "convert")) -delay $speed -loop 0 $(joinpath(anim.dir, "*.png")) -alpha off $fn`)
# prefix = get(ENV, "MAGICK_CONFIGURE_PATH", "")
run(`convert -delay $speed -loop 0 $(joinpath(anim.dir, "*.png")) -alpha off $fn`)
catch err
warn("""Tried to create gif using convert (ImageMagick), but got error: $err
@@ -56,7 +56,7 @@ end
# write out html to view the gif... note the rand call which is a hack so the image doesn't get cached
function Base.writemime(io::IO, ::MIME"text/html", agif::AnimatedGif)
write(io, "<img src=\"$(relpath(agif.filename))?$(rand())>\" />")
write(io, "<img src=\"$(relpath(agif.filename))?$(rand())>\" />")
end
+1
View File
@@ -62,6 +62,7 @@ const _arg_desc = KW(
:overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).",
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
:dpi => "Number. Dots Per Inch of output figures",
# subplot args
:title => "String. Subplot title.",
+2
View File
@@ -216,6 +216,7 @@ const _plot_defaults = KW(
:html_output_format => :auto,
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
# the parent layout and the relative bounding box of inset subplots
:dpi => DPI, # dots per inch for images, etc
)
@@ -432,6 +433,7 @@ add_aliases(:title_location, :title_loc, :titleloc, :title_position, :title_pos,
add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesanns, :series_annotation)
add_aliases(:html_output_format, :format, :fmt, :html_format)
add_aliases(:orientation, :direction, :dir)
add_aliases(:inset_subplots, :inset, :floating)
# add all pluralized forms to the _keyAliases dict
+226 -24
View File
@@ -29,68 +29,270 @@ supported_args(::GLVisualizeBackend) = merge_with_base_supported([
# :clims,
# :inset_subplots,
])
supported_types(::GLVisualizeBackend) = [:surface]
supported_types(::GLVisualizeBackend) = [:surface, :scatter, :scatter3d, :path, :path3d]
supported_styles(::GLVisualizeBackend) = [:auto, :solid]
supported_markers(::GLVisualizeBackend) = [:none, :auto, :circle]
supported_markers(::GLVisualizeBackend) = vcat([:none, :auto, :circle], collect(keys(_gl_marker_map)))
supported_scales(::GLVisualizeBackend) = [:identity]
is_subplot_supported(::GLVisualizeBackend) = false
is_subplot_supported(::GLVisualizeBackend) = true
# --------------------------------------------------------------------------------------
function _initialize_backend(::GLVisualizeBackend; kw...)
@eval begin
import GLVisualize
import GLVisualize, GeometryTypes, GLAbstraction, GLWindow
import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0
export GLVisualize
# TODO: remove this when PlotUtils is registered
import PlotUtils
end
end
# ---------------------------------------------------------------------------
immutable GLScreenWrapper
window
end
# initialize the figure/window
function _create_backend_figure(plt::Plot{GLVisualizeBackend})
# init a window
window = GLVisualize.glscreen()
@async GLVisualize.renderloop(window)
window
# init a screen
screen = if isdefined(GLVisualize, :ROOT_SCREEN)
GLVisualize.ROOT_SCREEN
else
s = GLVisualize.glscreen()
@async GLVisualize.renderloop(s)
s
end
empty!(screen)
screen
end
function gl_display(plt::Plot{GLVisualizeBackend})
for sp in plt.subplots
# TODO: setup subplot
# ---------------------------------------------------------------------------
# size as a percentage of the window size
function gl_relative_size(plt::Plot{GLVisualizeBackend}, msize::Number)
winsz = min(plt[:size]...)
Float32(msize / winsz)
end
const _gl_marker_map = KW(
:rect => '■',
:star5 => '★',
:diamond => '◆',
:hexagon => '⬢',
:cross => '✚',
:xcross => '❌',
:utriangle => '▲',
:dtriangle => '▼',
:pentagon => '⬟',
:octagon => '⯄',
:star4 => '✦',
:star6 => '✶',
:star8 => '✷',
:vline => '┃',
:hline => '━',
)
# create a marker/shape type
function gl_marker(shape::Symbol, msize::Number, _3d::Bool)
GeometryTypes.HyperSphere((_3d ? Point3f0 : Point2f0)(0), msize)
end
gl_color(c::RGBA{Float32}) = c
# convert to RGBA
function gl_color(c, a=nothing)
c = convertColor(c, a)
RGBA{Float32}(getColor(c))
end
function gl_viewport(bb, rect)
l, b, bw, bh = bb
rw, rh = rect.w, rect.h
GLVisualize.SimpleRectangle(
round(Int, rect.x + rw * l),
round(Int, rect.y + rh * b),
round(Int, rw * bw),
round(Int, rh * bh)
)
end
gl_make_points(x, y) = Point2f0[Point2f0(x[i], y[i]) for i=1:length(x)]
gl_make_points(x, y, z) = Point3f0[Point3f0(x[i], y[i], z[i]) for i=1:length(x)]
function gl_draw_lines_2d(x, y, color, linewidth, sp_screen)
color = gl_color(color)
thickness = Float32(linewidth)
for rng in iter_segments(x, y)
n = length(rng)
n < 2 && continue
viz = GLVisualize.visualize(
gl_make_points(x[rng], y[rng]),
n==2 ? :linesegment : :lines,
color=color,
thickness = Float32(linewidth)
)
GLVisualize.view(viz, sp_screen, camera=:orthographic_pixel)
end
end
function gl_draw_lines_3d(x, y, z, color, linewidth, sp_screen)
color = gl_color(color)
thickness = Float32(linewidth)
for rng in iter_segments(x, y, z)
n = length(rng)
n < 2 && continue
viz = GLVisualize.visualize(
gl_make_points(x[rng], y[rng], z[rng]),
n==2 ? :linesegment : :lines,
color=color,
thickness = Float32(linewidth)
)
GLVisualize.view(viz, sp_screen, camera=:perspective)
end
end
function gl_annotate(sp::Subplot{GLVisualizeBackend}, x, y, txt::PlotText)
end
function gl_draw_axes_2d(sp::Subplot{GLVisualizeBackend})
sp_screen = sp.o
xaxis = sp[:xaxis]
xmin, xmax = axis_limits(xaxis)
yaxis = sp[:yaxis]
ymin, ymax = axis_limits(yaxis)
# x axis
xsegs, ysegs = Segments(), Segments()
ticksz = 0.03*(ymax-ymin)
push!(xsegs, [xmin,xmax]); push!(ysegs, [ymin,ymin])
for tick in PlotUtils.optimize_ticks(xmin, xmax)[1]
push!(xsegs, [tick,tick]); push!(ysegs, [ymin,ymin+ticksz])
# TODO: add the ticklabel
end
gl_draw_lines_2d(xsegs.pts, ysegs.pts, xaxis[:foreground_color_border], 1, sp_screen)
# y axis
xsegs, ysegs = Segments(), Segments()
push!(xsegs, [xmin,xmin]); push!(ysegs, [ymin,ymax])
for tick in PlotUtils.optimize_ticks(xmin, xmax)[1]
push!(xsegs, [xmin,xmin+ticksz]); push!(ysegs, [tick,tick])
# TODO: add the ticklabel
end
gl_draw_lines_2d(xsegs.pts, ysegs.pts, yaxis[:foreground_color_border], 1, sp_screen)
end
# ---------------------------------------------------------------------------
# draw everything
function gl_display(plt::Plot{GLVisualizeBackend})
screen = plt.o
sw, sh = plt[:size]
sw, sh = sw*px, sh*px
for (name, sp) in plt.spmap
_3d = is3d(sp)
camera = _3d ? :perspective : :orthographic_pixel
# camera = :perspective
# initialize the sub-screen for this subplot
# note: we create a lift function to update the size on resize
rel_bbox = bbox_to_pcts(bbox(sp), sw, sh)
f = rect -> gl_viewport(rel_bbox, rect)
sp_screen = GLVisualize.Screen(
screen,
name = name,
area = GLVisualize.const_lift(f, screen.area)
)
sp.o = sp_screen
if !is3d(sp)
gl_draw_axes_2d(sp)
end
# loop over the series and add them to the subplot
for series in series_list(sp)
# TODO: setup series
d = series.d
st = d[:seriestype]
x, y, z = map(Float32, d[:x]), map(Float32, d[:y]), d[:z]
x, y = map(Float32, d[:x]), map(Float32, d[:y])
msize = gl_relative_size(plt, d[:markersize])
if st == :surface
viz = if st == :surface
# TODO: can pass just the ranges and surface
ismatrix(x) || (x = repmat(x', length(y), 1))
ismatrix(y) || (y = repmat(y, 1, length(x)))
z = transpose_z(d, map(Float32, z.surf), false)
z = transpose_z(d, map(Float32, d[:z].surf), false)
viz = GLVisualize.visualize((x, y, z), :surface)
GLVisualize.view(viz, plt.o)
return
GLVisualize.view(viz, sp_screen, camera = :perspective)
else
error("Series type $st not supported by GLVisualize")
end
# paths and scatters
_3d && (z = map(Float32, d[:z]))
# paths?
lw = d[:linewidth]
if lw > 0
c = gl_color(d[:linecolor], d[:linealpha])
if _3d
gl_draw_lines_3d(x, y, z, c, lw, sp_screen)
else
gl_draw_lines_2d(x, y, c, lw, sp_screen)
end
end
# markers?
if st in (:scatter, :scatter3d) || d[:markershape] != :none
extrakw = KW()
c = gl_color(d[:markercolor], d[:markeralpha])
# get the marker
shape = d[:markershape]
shape = get(_gl_marker_map, shape, shape)
marker = if isa(shape, Char)
# extrakw[:scale] = Vec2f0(_3d ? 0.6*d[:markersize] : msize)
extrakw[:scale] = Vec2f0(msize)
shape
else
gl_marker(d[:markershape], msize, _3d)
end
if !_3d
extrakw[:billboard] = true
end
points = _3d ? gl_make_points(x,y,z) : gl_make_points(x,y)
viz = GLVisualize.visualize(
(marker, points);
color = c,
extrakw...
)
GLVisualize.view(viz, sp_screen, camera = camera)
# TODO: might need to switch to these forms later?
# GLVisualize.visualize((marker ,(x, y, z)))
#GLVisualize.visualize((marker , map(Point3f0, zip(x, y, z),
# billboard=true
#))
end
end
end
GLAbstraction.center!(sp_screen, camera)
end
# TODO: render one frame at a time? (no renderloop)
# GLWindow.render_frame(screen)
end
# ----------------------------------------------------------------
function _update_plot_object(plt::Plot{GLVisualizeBackend})
gl_display(plt)
end
# function _writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{GLVisualizeBackend})
# # TODO: write a png to io
# end
function _display(plt::Plot{GLVisualizeBackend})
gl_display(plt)
end
+79 -73
View File
@@ -41,7 +41,6 @@ supported_scales(::GRBackend) = [:identity, :log10]
is_subplot_supported(::GRBackend) = true
function _initialize_backend(::GRBackend; kw...)
@eval begin
import GR
@@ -121,33 +120,6 @@ gr_set_textcolor(c, a=nothing) = GR.settextcolorind(gr_getcolorind(c, a))
# --------------------------------------------------------------------------------------
function gr_setmarkershape(d)
if d[:markershape] != :none
shape = d[:markershape]
if isa(shape, Shape)
d[:vertices] = vertices(shape)
else
GR.setmarkertype(gr_markertype[shape])
d[:vertices] = :none
end
end
end
function gr_polymarker(d, x, y)
if d[:vertices] != :none
vertices= d[:vertices]
dx = Float64[el[1] for el in vertices] * 0.03
dy = Float64[el[2] for el in vertices] * 0.03
GR.selntran(0)
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
# draw line segments, splitting x/y into contiguous/finite segments
# note: this can be used for shapes by passing func `GR.fillarea`
@@ -260,48 +232,64 @@ function normalize_zvals(zv::AVec)
end
end
# ---------------------------------------------------------
function gr_draw_markers(d::KW, x, y, msize, mz, c, a)
if length(x) > 0
mz == nothing && gr_set_markercolor(c, a)
if typeof(msize) <: Number && mz == nothing
# draw the markers all the same
GR.setmarkersize(msize)
gr_polymarker(d, x, y)
else
# draw each marker differently
for i = 1:length(x)
if mz != nothing
ci = round(Int, 1000 + mz[i] * 255)
GR.setmarkercolorind(ci)
end
GR.setmarkersize(isa(msize, Number) ? msize : msize[mod1(i, length(msize))])
gr_polymarker(d, [x[i]], [y[i]])
# draw ONE Shape
function gr_draw_marker(xi, yi, msize, shape::Shape)
sx, sy = shape_coords(shape)
GR.selntran(0)
xi, yi = GR.wctondc(xi, yi)
GR.fillarea(xi + sx * 0.0015msize,
yi + sy * 0.0015msize)
GR.selntran(1)
end
# draw ONE symbol marker
function gr_draw_marker(xi, yi, msize::Number, shape::Symbol)
GR.setmarkertype(gr_markertype[shape])
GR.setmarkersize(0.3msize)
GR.polymarker([xi], [yi])
end
# draw the markers, one at a time
function gr_draw_markers(d::KW, x, y, msize, mz)
shape = d[:markershape]
if shape != :none
for i=1:length(x)
msi = cycle(msize, i)
cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor
cfuncind = isa(shape, Shape) ? GR.setfillcolorind : GR.setmarkercolorind
# draw a filled in shape, slightly bigger, to estimate a stroke
cfunc(d[:markerstrokecolor], d[:markerstrokealpha])
gr_draw_marker(x[i], y[i], msi*1.2, shape, )
# draw the shape
if mz == nothing
cfunc(d[:markercolor], d[:markeralpha])
else
# pick a color from the pre-loaded gradient
ci = round(Int, 1000 + cycle(mz, i) * 255)
cfuncind(ci)
end
gr_draw_marker(x[i], y[i], msi, shape)
end
end
end
function gr_draw_markers(series::Series, x, y)
isempty(x) && return
d = series.d
msize = 0.5 * d[:markersize]
mz = normalize_zvals(d[:marker_z])
# draw the marker
gr_setmarkershape(d)
GR.setfillintstyle(GR.INTSTYLE_SOLID)
gr_draw_markers(d, x, y, msize, mz, d[:markercolor], d[:markeralpha])
# # draw the stroke
# GR.setfillintstyle(GR.INTSTYLE_HOLLOW)
# gr_draw_markers(d, x, y, msize, mz, d[:markerstrokecolor], d[:markerstrokealpha])
gr_draw_markers(d, x, y, d[:markersize], mz)
if mz != nothing
gr_colorbar(d[:subplot])
end
end
# ---------------------------------------------------------
function gr_set_line(w, style, c, a)
GR.setlinetype(gr_linetype[style])
@@ -495,6 +483,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
data_lims = gr_xy_axislims(sp)
xmin, xmax, ymin, ymax = data_lims
scale = 0
xtick, ytick = 1, 1
if xmax > xmin && ymax > ymin
# NOTE: for log axes, the major_x and major_y - if non-zero (omit labels) - control the minor grid lines (1 = draw 9 minor grid lines, 2 = no minor grid lines)
# NOTE: for log axes, the x_tick and y_tick - if non-zero (omit axes) - only affect the output appearance (1 = nomal, 2 = scientiic notation)
@@ -774,14 +763,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.selntran(1)
elseif st == :shape
# draw the shapes
gr_set_line(d[:markerstrokewidth], :solid, d[:markerstrokecolor], d[:markerstrokealpha])
gr_polyline(d[:x], d[:y])
# draw the interior
gr_set_fill(d[:markercolor], d[:markeralpha])
gr_set_fill(d[:fillcolor], d[:fillalpha])
gr_polyline(d[:x], d[:y], GR.fillarea)
# draw the shapes
gr_set_line(d[:linewidth], :solid, d[:linecolor], d[:linealpha])
gr_polyline(d[:x], d[:y])
elseif st == :image
@@ -839,21 +827,36 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
should_add_to_legend(series) || continue
d = series.d
st = d[:seriestype]
GR.setlinewidth(d[:linewidth])
gr_set_line(d[:linewidth], d[:linestyle], d[:linecolor], d[:linealpha])
if st == :path
gr_set_linecolor(d[:linecolor], d[:linealpha])
GR.setlinetype(gr_linetype[d[:linestyle]])
GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos])
elseif st == :shape
gr_set_fill(d[:fillcolor], d[:fillalpha])
l, r = xpos-0.07, xpos-0.01
b, t = ypos-0.4dy, ypos+0.4dy
x = [l, r, r, l, l]
y = [b, b, t, t, b]
gr_polyline(x, y, GR.fillarea)
gr_polyline(x, y)
end
if st == :scatter || d[:markershape] != :none
gr_set_markercolor(d[:markercolor], d[:markeralpha])
gr_setmarkershape(d)
if st == :path
gr_polymarker(d, [xpos - 0.06, xpos - 0.02], [ypos, ypos])
else
gr_polymarker(d, [xpos - 0.06, xpos - 0.04, xpos - 0.02], [ypos, ypos, ypos])
end
end
gr_draw_markers(d, xpos-[0.06,0.02], [ypos,ypos], 10, nothing)
# shape = d[:markershape]
# if shape != :none #st == :scatter || d[:markershape] != :none
# msize = 10
# for xoff in [0.06,0.02]
# gr_set_markercolor(d[:markerstrokecolor], d[:markerstrokealpha])
# gr_draw_marker(xpos-xoff, ypos, msize*1.1, shape)
# gr_set_markercolor(d[:markercolor], d[:markeralpha])
# gr_draw_marker(xpos-xoff, ypos, msize, shape)
# end
# # gr_setmarkershape(d)
# # if st == :path
# # gr_polymarker(d, [xpos - 0.06, xpos - 0.02], [ypos, ypos])
# # else
# # gr_polymarker(d, [xpos - 0.06, xpos - 0.04, xpos - 0.02], [ypos, ypos, ypos])
# # end
# end
if typeof(d[:label]) <: Array
i += 1
lab = d[:label][i]
@@ -896,11 +899,14 @@ for (mime, fmt) in _gr_mimeformats
@eval function _writemime(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GRBackend})
GR.emergencyclosegks()
wstype = haskey(ENV, "GKS_WSTYPE") ? ENV["GKS_WSTYPE"] : "0"
filepath = tempname() * "." * $fmt
ENV["GKS_WSTYPE"] = $fmt
ENV["GKS_FILEPATH"] = filepath
gr_display(plt)
GR.emergencyclosegks()
write(io, readall("gks." * $fmt))
write(io, readall(filepath))
ENV["GKS_WSTYPE"] = wstype
rm(filepath)
end
end
+4 -4
View File
@@ -374,12 +374,12 @@ function plotly_series(plt::Plot, series::Series)
# @show map(length, (x,y,d_out[:x],d_out[:y]))
# @show d_out[:x] d_out[:y]
d_out[:fill] = "tozeroy"
d_out[:fillcolor] = webcolor(d[:markercolor], d[:markeralpha])
d_out[:fillcolor] = webcolor(d[:fillcolor], d[:fillalpha])
if d[:markerstrokewidth] > 0
d_out[:line] = KW(
:color => webcolor(d[:markerstrokecolor], d[:markerstrokealpha]),
:width => d[:markerstrokewidth],
:dash => string(d[:markerstrokestyle]),
:color => webcolor(d[:linecolor], d[:linealpha]),
:width => d[:linewidth],
:dash => string(d[:linestyle]),
)
end
+1
View File
@@ -5,6 +5,7 @@ supported_args(::PlotlyJSBackend) = supported_args(PlotlyBackend())
supported_types(::PlotlyJSBackend) = supported_types(PlotlyBackend())
supported_styles(::PlotlyJSBackend) = supported_styles(PlotlyBackend())
supported_markers(::PlotlyJSBackend) = supported_markers(PlotlyBackend())
supported_scales(::PlotlyJSBackend) = supported_scales(PlotlyBackend())
is_subplot_supported(::PlotlyJSBackend) = true
is_string_supported(::PlotlyJSBackend) = true
+106 -98
View File
@@ -30,11 +30,12 @@ supported_args(::PyPlotBackend) = merge_with_base_supported([
:match_dimensions,
:clims,
:inset_subplots,
:dpi,
])
supported_types(::PyPlotBackend) = [
:path, :steppre, :steppost, :shape,
:scatter, :histogram2d, :hexbin, :histogram,
:bar,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
@@ -62,6 +63,7 @@ function _initialize_backend(::PyPlotBackend)
const pyticker = PyPlot.pywrap(PyPlot.pyimport("matplotlib.ticker"))
const pycmap = PyPlot.pywrap(PyPlot.pyimport("matplotlib.cm"))
const pynp = PyPlot.pywrap(PyPlot.pyimport("numpy"))
pynp.seterr(invalid="ignore")
const pytransforms = PyPlot.pywrap(PyPlot.pyimport("matplotlib.transforms"))
const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections"))
const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d"))
@@ -139,7 +141,7 @@ function py_path(x, y)
mat[i,1] = x[i]
mat[i,2] = y[i]
nan = !ok(x[i], y[i])
codes[i] = if nan
codes[i] = if nan && i>1
_path_CLOSEPOLY
else
lastnan ? _path_MOVETO : _path_LINETO
@@ -188,13 +190,13 @@ function py_stepstyle(seriestype::Symbol)
return "default"
end
# untested... return a FontProperties object from a Plots.Font
function py_font(font::Font)
pyfont.pymember("FontProperties")(
family = font.family,
size = font.size
)
end
# # untested... return a FontProperties object from a Plots.Font
# function py_font(font::Font)
# pyfont.pymember("FontProperties")(
# family = font.family,
# size = font.size
# )
# end
function get_locator_and_formatter(vals::AVec)
pyticker.pymember("FixedLocator")(1:length(vals)), pyticker.pymember("FixedFormatter")(vals)
@@ -327,6 +329,10 @@ function py_bbox_title(ax)
bb
end
function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz)
ptsz * DPI / plt[:dpi]
end
# ---------------------------------------------------------------------------
# Create the window/figure for this backend.
@@ -419,7 +425,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = d[:label],
zorder = plt.n,
color = py_linecolor(d),
linewidth = d[:linewidth],
linewidth = py_dpi_scale(plt, d[:linewidth]),
linestyle = py_linestyle(st, d[:linestyle]),
solid_capstyle = "round",
drawstyle = py_stepstyle(st)
@@ -434,7 +440,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:label => d[:label],
:zorder => plt.n,
:cmap => py_linecolormap(d),
:linewidth => d[:linewidth],
:linewidth => py_dpi_scale(plt, d[:linewidth]),
:linestyle => py_linestyle(st, d[:linestyle])
)
handle = if is3d(st)
@@ -469,7 +475,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:shrinkB => 0,
:edgecolor => py_linecolor(d),
:facecolor => py_linecolor(d),
:linewidth => d[:linewidth],
:linewidth => py_dpi_scale(plt, d[:linewidth]),
:linestyle => py_linestyle(st, d[:linestyle]),
)
add_arrows(x, y) do xyprev, xy
@@ -485,28 +491,28 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
end
if st == :bar
bw = d[:bar_width]
if bw == nothing
bw = mean(diff(isvertical(d) ? x : y))
end
extrakw[isvertical(d) ? :width : :height] = bw
fr = get(d, :fillrange, nothing)
if fr != nothing
extrakw[:bottom] = fr
d[:fillrange] = nothing
end
handle = ax[isvertical(d) ? :bar : :barh](x, y;
label = d[:label],
zorder = plt.n,
color = py_fillcolor(d),
edgecolor = py_linecolor(d),
linewidth = d[:linewidth],
align = d[:bar_edges] ? "edge" : "center",
extrakw...
)[1]
push!(handles, handle)
end
# if st == :bar
# bw = d[:bar_width]
# if bw == nothing
# bw = mean(diff(isvertical(d) ? x : y))
# end
# extrakw[isvertical(d) ? :width : :height] = bw
# fr = get(d, :fillrange, nothing)
# if fr != nothing
# extrakw[:bottom] = fr
# d[:fillrange] = nothing
# end
# handle = ax[isvertical(d) ? :bar : :barh](x, y;
# label = d[:label],
# zorder = plt.n,
# color = py_fillcolor(d),
# edgecolor = py_linecolor(d),
# linewidth = d[:linewidth],
# align = d[:bar_edges] ? "edge" : "center",
# extrakw...
# )[1]
# push!(handles, handle)
# end
# if st == :sticks
# extrakw[isvertical(d) ? :width : :height] = 0.0
@@ -548,62 +554,62 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = d[:label],
zorder = plt.n + 0.5,
marker = py_marker(d[:markershape]),
s = d[:markersize] .^ 2,
s = py_dpi_scale(plt, d[:markersize] .^ 2),
edgecolors = py_markerstrokecolor(d),
linewidths = d[:markerstrokewidth],
linewidths = py_dpi_scale(plt, d[:markerstrokewidth]),
extrakw...
)
push!(handles, handle)
end
if st == :histogram
handle = ax[:hist](y;
label = d[:label],
zorder = plt.n,
color = py_fillcolor(d),
edgecolor = py_linecolor(d),
linewidth = d[:linewidth],
bins = d[:bins],
normed = d[:normalize],
weights = d[:weights],
orientation = (isvertical(d) ? "vertical" : "horizontal"),
histtype = (d[:bar_position] == :stack ? "barstacked" : "bar")
)[3]
push!(handles, handle)
# if st == :histogram
# handle = ax[:hist](y;
# label = d[:label],
# zorder = plt.n,
# color = py_fillcolor(d),
# edgecolor = py_linecolor(d),
# linewidth = d[:linewidth],
# bins = d[:bins],
# normed = d[:normalize],
# weights = d[:weights],
# orientation = (isvertical(d) ? "vertical" : "horizontal"),
# histtype = (d[:bar_position] == :stack ? "barstacked" : "bar")
# )[3]
# push!(handles, handle)
# expand the extrema... handle is a list of Rectangle objects
for rect in handle
xmin, ymin, xmax, ymax = rect[:get_bbox]()[:extents]
expand_extrema!(sp, xmin, xmax, ymin, ymax)
# expand_extrema!(sp[:xaxis], (xmin, xmax))
# expand_extrema!(sp[:yaxis], (ymin, ymax))
end
end
# # expand the extrema... handle is a list of Rectangle objects
# for rect in handle
# xmin, ymin, xmax, ymax = rect[:get_bbox]()[:extents]
# expand_extrema!(sp, xmin, xmax, ymin, ymax)
# # expand_extrema!(sp[:xaxis], (xmin, xmax))
# # expand_extrema!(sp[:yaxis], (ymin, ymax))
# end
# end
if st == :histogram2d
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
end
handle = ax[:hist2d](x, y;
label = d[:label],
zorder = plt.n,
bins = d[:bins],
normed = d[:normalize],
weights = d[:weights],
cmap = py_fillcolormap(d), # applies to the pcolorfast object
extrakw...
)[4]
push!(handles, handle)
needs_colorbar = true
# if st == :histogram2d
# clims = sp[:clims]
# if is_2tuple(clims)
# isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
# isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
# end
# handle = ax[:hist2d](x, y;
# label = d[:label],
# zorder = plt.n,
# bins = d[:bins],
# normed = d[:normalize],
# weights = d[:weights],
# cmap = py_fillcolormap(d), # applies to the pcolorfast object
# extrakw...
# )[4]
# push!(handles, handle)
# needs_colorbar = true
# expand the extrema... handle is a AxesImage object
expand_extrema!(sp, handle[:get_extent]()...)
# xmin, xmax, ymin, ymax = handle[:get_extent]()
# expand_extrema!(sp[:xaxis], (xmin, xmax))
# expand_extrema!(sp[:yaxis], (ymin, ymax))
end
# # expand the extrema... handle is a AxesImage object
# expand_extrema!(sp, handle[:get_extent]()...)
# # xmin, xmax, ymin, ymax = handle[:get_extent]()
# # expand_extrema!(sp[:xaxis], (xmin, xmax))
# # expand_extrema!(sp[:yaxis], (ymin, ymax))
# end
if st == :hexbin
clims = sp[:clims]
@@ -615,7 +621,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = d[:label],
zorder = plt.n,
gridsize = d[:bins],
linewidths = d[:linewidth],
linewidths = py_dpi_scale(plt, d[:linewidth]),
edgecolors = py_linecolor(d),
cmap = py_fillcolormap(d), # applies to the pcolorfast object
extrakw...
@@ -655,7 +661,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
handle = ax[:contour](x, y, z, levelargs...;
label = d[:label],
zorder = plt.n,
linewidths = d[:linewidth],
linewidths = py_dpi_scale(plt, d[:linewidth]),
linestyles = py_linestyle(st, d[:linestyle]),
cmap = py_linecolormap(d),
extrakw...
@@ -702,7 +708,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
zorder = plt.n,
rstride = 1,
cstride = 1,
linewidth = d[:linewidth],
linewidth = py_dpi_scale(plt, d[:linewidth]),
edgecolor = py_linecolor(d),
extrakw...
)
@@ -738,7 +744,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = d[:label],
zorder = plt.n,
cmap = py_fillcolormap(d),
linewidth = d[:linewidth],
linewidth = py_dpi_scale(plt, d[:linewidth]),
edgecolor = py_linecolor(d),
extrakw...
)
@@ -815,9 +821,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
patches = pypatches.pymember("PathPatch")(path;
label = d[:label],
zorder = plt.n,
edgecolor = py_markerstrokecolor(d),
facecolor = py_markercolor(d),
linewidth = d[:markerstrokewidth],
edgecolor = py_linecolor(d),
facecolor = py_fillcolor(d),
linewidth = py_dpi_scale(plt, d[:linewidth]),
fill = true
)
handle = ax[:add_patch](patches)
@@ -1010,9 +1016,11 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
w, h = plt[:size]
fig = plt.o
fig[:clear]()
fig[:set_size_inches](px2inch(w), px2inch(h), forward = true)
# fig[:set_size_inches](px2inch(w), px2inch(h), forward = true)
dpi = plt[:dpi]
fig[:set_size_inches](w/dpi, h/dpi, forward = true)
fig[:set_facecolor](py_color(plt[:background_color_outside]))
fig[:set_dpi](DPI)
fig[:set_dpi](dpi)
# resize the window
PyPlot.plt[:get_current_fig_manager]()[:resize](w, h)
@@ -1050,7 +1058,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
:title
end
ax[func][:set_text](sp[:title])
ax[func][:set_fontsize](sp[:titlefont].pointsize)
ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefont].pointsize))
ax[func][:set_color](py_color(sp[:foreground_color_title]))
# ax[:set_title](sp[:title], loc = loc)
end
@@ -1067,9 +1075,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
if get(axis.d, :flip, false)
ax[Symbol("invert_", letter, "axis")]()
end
ax[axissym][:label][:set_fontsize](axis[:guidefont].pointsize)
ax[axissym][:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefont].pointsize))
for lab in ax[Symbol("get_", letter, "ticklabels")]()
lab[:set_fontsize](axis[:tickfont].pointsize)
lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfont].pointsize))
lab[:set_rotation](axis[:rotation])
end
if sp[:grid]
@@ -1147,7 +1155,7 @@ function py_add_annotations(sp::Subplot{PyPlotBackend}, x, y, val::PlotText)
horizontalalignment = val.font.halign == :hcenter ? "center" : string(val.font.halign),
verticalalignment = val.font.valign == :vcenter ? "center" : string(val.font.valign),
rotation = val.font.rotation * 180 / π,
size = val.font.pointsize,
size = py_dpi_scale(sp.plt, val.font.pointsize),
zorder = 999
)
end
@@ -1190,7 +1198,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
if should_add_to_legend(series)
# add a line/marker and a label
push!(handles, if series.d[:seriestype] == :histogram
PyPlot.plt[:Line2D]((0,1),(0,0), color=py_fillcolor(series.d), linewidth=4)
PyPlot.plt[:Line2D]((0,1),(0,0), color=py_fillcolor(series.d), linewidth=py_dpi_scale(plt, 4))
else
series.d[:serieshandle][1]
end)
@@ -1204,7 +1212,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
labels,
loc = get(_pyplot_legend_pos, leg, "best"),
scatterpoints = 1,
fontsize = sp[:legendfont].pointsize
fontsize = py_dpi_scale(plt, sp[:legendfont].pointsize)
# framealpha = 0.6
)
leg[:set_zorder](1000)
@@ -1277,7 +1285,7 @@ for (mime, fmt) in _pyplot_mimeformats
# figsize = map(px2inch, plt[:size]),
facecolor = fig.o["get_facecolor"](),
edgecolor = "none",
dpi = DPI
dpi = plt[:dpi]
)
end
end
+33
View File
@@ -1,6 +1,33 @@
abstract ColorScheme
Base.getindex(scheme::ColorScheme, i::Integer) = getColor(scheme, i)
export
cgrad
cgrad() = default_gradient()
function cgrad(arg, values = nothing; alpha = nothing, scale = :identity)
colors = ColorGradient(arg, alpha=alpha).colors
values = if values != nothing
values
elseif scale in (:log, :log10)
log10(linspace(1,10,30))
elseif scale == :log2
log2(linspace(1,2,30))
elseif scale == :ln
log(linspace(1,pi,30))
elseif scale in (:exp, :exp10)
(exp10(linspace(0,1,30)) - 1) / 9
else
linspace(0, 1, length(colors))
end
ColorGradient(colors, values)
end
# --------------------------------------------------------------
getColor(scheme::ColorScheme) = getColor(scheme, 1)
getColorVector(scheme::ColorScheme) = [getColor(scheme)]
@@ -103,6 +130,12 @@ immutable ColorGradient <: ColorScheme
end
end
Base.getindex(cs::ColorGradient, i::Integer) = getColor(cs, i)
Base.getindex(cs::ColorGradient, z::Number) = getColorZ(cs, z)
# create a gradient from a symbol (blues, reds, etc) and vector of boundary values
function ColorGradient{T<:Real}(s::Symbol, vals::AVec{T} = 0:0; kw...)
haskey(_gradients, s) || error("Invalid gradient symbol. Choose from: ", sort(collect(keys(_gradients))))
+2 -2
View File
@@ -303,8 +303,8 @@ PlotExample("Boxplot and Violin series recipes",
[:(begin
import RDatasets
singers = RDatasets.dataset("lattice", "singer")
violin(singers, :VoicePart, :Height, marker = (0.2, :blue, stroke(0)))
boxplot!(singers, :VoicePart, :Height, marker = (0.3, :orange, stroke(2)))
violin(singers, :VoicePart, :Height, line = 0, fill = (0.2, :blue))
boxplot!(singers, :VoicePart, :Height, line = (2,:black), fill = (0.3, :orange))
end)]
)
+41 -4
View File
@@ -101,19 +101,46 @@ end
Base.show(io::IO, layout::AbstractLayout) = print(io, "$(typeof(layout))$(size(layout))")
make_measure_hor(n::Number) = n * w
make_measure_hor(m::Measure) = m
make_measure_vert(n::Number) = n * h
make_measure_vert(m::Measure) = m
function bbox(x, y, w, h, oarg1::Symbol, originargs::Symbol...)
oargs = vcat(oarg1, originargs...)
orighor = :left
origver = :top
for oarg in oargs
if oarg in (:left, :right)
orighor = oarg
elseif oarg in (:top, :bottom)
origver = oarg
else
warn("Unused origin arg in bbox construction: $oarg")
end
end
bbox(x, y, w, h; h_anchor = orighor, v_anchor = origver)
end
# create a new bbox
function bbox(x, y, w, h; h_anchor = :left, v_anchor = :top)
function bbox(x, y, width, height; h_anchor = :left, v_anchor = :top)
x = make_measure_hor(x)
y = make_measure_vert(y)
width = make_measure_hor(width)
height = make_measure_vert(height)
left = if h_anchor == :left
x
else
x - w * (h_anchor == :right ? 1.0 : 0.5)
1w - x - width
end
top = if v_anchor == :top
y
else
y - h * (v_anchor == :bottom ? 1.0 : 0.5)
1h - y - height
end
BoundingBox(left, top, w, h)
BoundingBox(left, top, width, height)
end
# this is the available area for drawing everything in this layout... as percentages of total canvas
@@ -664,6 +691,16 @@ function link_axes!(layout::GridLayout, link::Symbol)
link_axes!(layout.grid[r,:], :yaxis)
end
end
if link == :square
sps = filter(l -> isa(l, Subplot), layout.grid)
if !isempty(sps)
base_axis = sps[1][:xaxis]
for sp in sps
link_axes!(base_axis, sp[:xaxis])
link_axes!(base_axis, sp[:yaxis])
end
end
end
if link == :all
link_axes!(layout.grid, :xaxis)
link_axes!(layout.grid, :yaxis)
+11
View File
@@ -149,6 +149,12 @@ end
# for writing to io streams... first prepare, then callback
for mime in keys(_mimeformats)
@eval function _writemime(io::IO, m, plt::Plot)
warn("_writemime is not defined for this backend. m=", string(m))
end
@eval function _display(plt::Plot)
warn("_display is not defined for this backend.")
end
@eval function Base.writemime(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
prepare_output(plt)
_writemime(io, m, plt)
@@ -222,6 +228,11 @@ function setup_ijulia()
global _ijulia_output
Dict{Compat.ASCIIString, ByteString}(_ijulia_output[1] => sprint(writemime, _ijulia_output[1], plt))
end
# default text/plain passes to html... handles Interact issues
function Base.writemime(io::IO, m::MIME"text/plain", plt::Plot)
writemime(io, MIME("text/html"), plt)
end
end
set_ijulia_output("text/html")
end
+117 -75
View File
@@ -162,8 +162,11 @@ end
# this method recursively applies series recipes when the seriestype is not supported
# natively by the backend
function _apply_series_recipe(plt::Plot, d::KW)
# replace seriestype aliases
st = d[:seriestype]
# @show st
st = d[:seriestype] = get(_typeAliases, st, st)
# if it's natively supported, finalize processing and pass along to the backend, otherwise recurse
if st in supported_types()
# getting ready to add the series... last update to subplot from anything
@@ -222,12 +225,13 @@ function _apply_series_recipe(plt::Plot, d::KW)
else
# get a sub list of series for this seriestype
datalist = try
RecipesBase.apply_recipe(d, Val{st}, d[:x], d[:y], d[:z])
catch
warn("Exception during apply_recipe(Val{$st}, ...) with types ($(typeof(d[:x])), $(typeof(d[:y])), $(typeof(d[:z])))")
rethrow()
end
datalist = RecipesBase.apply_recipe(d, Val{st}, d[:x], d[:y], d[:z])
# datalist = try
# RecipesBase.apply_recipe(d, Val{st}, d[:x], d[:y], d[:z])
# catch
# warn("Exception during apply_recipe(Val{$st}, ...) with types ($(typeof(d[:x])), $(typeof(d[:y])), $(typeof(d[:z])))")
# rethrow()
# end
# assuming there was no error, recursively apply the series recipes
for data in datalist
@@ -241,12 +245,15 @@ function _apply_series_recipe(plt::Plot, d::KW)
end
end
function command_idx(kw_list::AVec{KW}, kw::KW)
kw[:series_plotindex] - kw_list[1][:series_plotindex] + 1
end
# this is the core plotting function. recursively apply recipes to build
# a list of series KW dicts.
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
function _plot!(plt::Plot, d::KW, args...)
# d = plt.user_attr
d[:plot_object] = plt
# the grouping mechanism is a recipe on a GroupBy object
@@ -256,6 +263,40 @@ function _plot!(plt::Plot, d::KW, args...)
args = (extractGroupArgs(d[:group], args...), args...)
end
# if we were passed a vector/matrix of seriestypes and there's more than one row,
# we want to duplicate the inputs, once for each seriestype row.
kw_list = KW[]
still_to_process = if isempty(args)
[]
else
sts = get(d, :seriestype, :path)
if typeof(sts) <: AbstractArray
[begin
dc = copy(d)
dc[:seriestype] = sts[r,:]
RecipeData(dc, args)
end for r=1:size(sts,1)]
else
[RecipeData(copy(d), args)]
end
end
# remove subplot and axis args from d... they will be passed through in the kw_list
if !isempty(args)
for (k,v) in d
for defdict in (_subplot_defaults,
_axis_defaults,
_axis_defaults_byletter)
if haskey(defdict, k)
delete!(d, k)
end
end
end
end
# --------------------------------
# "USER RECIPES"
# --------------------------------
# for plotting recipes, swap out the args and update the parameter dictionary
# we are keeping a queue of series that still need to be processed.
@@ -263,8 +304,6 @@ function _plot!(plt::Plot, d::KW, args...)
# the recipe will return a list a Series objects... the ones that are
# finished (no more args) get added to the kw_list, and the rest go into the queue
# for processing.
kw_list = KW[]
still_to_process = isempty(args) ? [] : [RecipeData(copy(d), args)]
while !isempty(still_to_process)
# grab the first in line to be processed and pass it through apply_recipe
@@ -349,25 +388,59 @@ function _plot!(plt::Plot, d::KW, args...)
# don't allow something else to handle it
d[:smooth] = false
# merge in anything meant for plot/subplot/axis
for kw in kw_list
for (k,v) in kw
for defdict in (_plot_defaults,)
# _subplot_defaults,
# _axis_defaults,
# _axis_defaults_byletter)
if haskey(defdict, k)
d[k] = pop!(kw, k)
# --------------------------------
# "PLOT RECIPES"
# --------------------------------
# "plot recipe", which acts like a series type, and is processed before
# the plot layout is created, which allows for setting layouts and other plot-wide attributes.
# we get inputs which have been fully processed by "user recipes" and "type recipes",
# so we can expect standard vectors, surfaces, etc. No defaults have been set yet.
still_to_process = kw_list
kw_list = KW[]
while !isempty(still_to_process)
# Grab the first in line to be processed and pass it through apply_recipe
# to generate a list of RecipeData objects (data + attributes).
# If we applied a "plot recipe" without error, then add the returned datalist's KWs,
# otherwise we just add the original KW.
next_kw = shift!(still_to_process)
if !isa(get(next_kw, :seriestype, nothing), Symbol)
# seriestype was never set, or it's not a Symbol, so it can't be a plot recipe
push!(kw_list, next_kw)
continue
end
try
st = next_kw[:seriestype]
st = next_kw[:seriestype] = get(_typeAliases, st, st)
datalist = RecipesBase.apply_recipe(next_kw, Val{st}, plt)
for data in datalist
if data.d[:seriestype] == st
error("Plot recipe $st returned the same seriestype: $(data.d)")
end
push!(still_to_process, data.d)
end
catch err
if isa(err, MethodError)
push!(kw_list, next_kw)
else
rethrow()
end
end
end
# --------------------------------
# Plot/Subplot/Layout setup
# --------------------------------
# merge in anything meant for the Plot
for kw in kw_list, (k,v) in kw
haskey(_plot_defaults, k) && (d[k] = pop!(kw, k))
end
# TODO: init subplots here
_update_plot_args(plt, d)
if !plt.init
plt.o = _create_backend_figure(plt)
# DD(d)
# create the layout and subplots from the inputs
plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr)
@@ -383,6 +456,9 @@ function _plot!(plt::Plot, d::KW, args...)
# handle inset subplots
insets = plt[:inset_subplots]
if insets != nothing
if !(typeof(insets) <: AVec)
insets = [insets]
end
for inset in insets
parent, bb = is_2tuple(inset) ? inset : (nothing, inset)
P = typeof(parent)
@@ -396,29 +472,24 @@ function _plot!(plt::Plot, d::KW, args...)
sp = Subplot(backend(), parent=parent)
sp.plt = plt
sp.attr[:relative_bbox] = bb
push!(plt.subplots, sp)
sp.attr[:subplot_index] = length(plt.subplots)
push!(plt.subplots, sp)
push!(plt.inset_subplots, sp)
end
end
# we'll keep a map of subplot to an attribute override dict.
# any series which belong to that subplot
# Subplot/Axis attributes set by a user/series recipe apply only to the
# Subplot object which they belong to.
# TODO: allow matrices to still apply to all subplots
sp_attrs = Dict{Subplot,Any}()
for kw in kw_list
# get the Subplot object to which the series belongs
sp = get(kw, :subplot, :auto)
command_idx = kw[:series_plotindex] - kw_list[1][:series_plotindex] + 1
sp = if sp == :auto
cycle(plt.subplots, command_idx)
# mod1(command_idx, length(plt.subplots))
else
slice_arg(sp, command_idx)
end
sp = kw[:subplot] = get_subplot(plt, sp)
# idx = get_subplot_index(plt, sp)
attr = KW()
# get the Subplot object to which the series belongs.
sps = get(kw, :subplot, :auto)
sp = get_subplot(plt, cycle(sps == :auto ? plt.subplots : plt.subplots[sps], command_idx(kw_list,kw)))
kw[:subplot] = sp
attr = KW()
for (k,v) in kw
for defdict in (_subplot_defaults,
_axis_defaults,
@@ -431,60 +502,31 @@ function _plot!(plt::Plot, d::KW, args...)
sp_attrs[sp] = attr
end
# # just in case the backend needs to set up the plot (make it current or something)
# _prepare_plot_object(plt)
# first apply any args for the subplots
# override subplot/axis args. `sp_attrs` take precendence
for (idx,sp) in enumerate(plt.subplots)
# if we picked up any subplot-specific overrides, merge them here
attr = merge(d, get(sp_attrs, sp, KW()))
# DD(attr, "sp$idx")
_update_subplot_args(plt, sp, attr, idx, remove_pair = false)
end
# do we need to link any axes together?
link_axes!(plt.layout, plt[:link])
# !!! note: At this point, kw_list is fully decomposed into individual series... one KW per series. !!!
# !!! The next step is to recursively apply series recipes until the backend supports that series type !!!
# this is it folks!
# TODO: we probably shouldn't use i for tracking series index, but rather explicitly track it in recipes
# --------------------------------
# "SERIES RECIPES"
# --------------------------------
for kw in kw_list
command_idx = kw[:series_plotindex] - kw_list[1][:series_plotindex] + 1
# # get the Subplot object to which the series belongs
# sp = get(kw, :subplot, :auto)
# sp = if sp == :auto
# mod1(i,length(plt.subplots))
# else
# slice_arg(sp, i)
# end
# sp = kw[:subplot] = get_subplot(plt, sp)
sp = kw[:subplot]
idx = get_subplot_index(plt, sp)
# # strip out series annotations (those which are based on series x/y coords)
# # and add them to the subplot attr
# sp_anns = annotations(sp[:annotations])
# anns = annotations(pop!(kw, :series_annotations, []))
# if length(anns) > 0
# x, y = kw[:x], kw[:y]
# nx, ny, na = map(length, (x,y,anns))
# n = max(nx, ny, na)
# anns = [(x[mod1(i,nx)], y[mod1(i,ny)], text(anns[mod1(i,na)])) for i=1:n]
# end
# sp.attr[:annotations] = vcat(sp_anns, anns)
# we update subplot args in case something like the color palatte is part of the recipe
_update_subplot_args(plt, sp, kw, idx)
# # we update subplot args in case something like the color palatte is part of the recipe
# _update_subplot_args(plt, sp, kw, idx)
# set default values, select from attribute cycles, and generally set the final attributes
_add_defaults!(kw, plt, sp, command_idx)
_add_defaults!(kw, plt, sp, command_idx(kw_list,kw))
# now we have a fully specified series, with colors chosen. we must recursively handle
# series recipes, which dispatch on seriestype. If a backend does not natively support a seriestype,
@@ -495,12 +537,12 @@ function _plot!(plt::Plot, d::KW, args...)
_apply_series_recipe(plt, kw)
end
# --------------------------------
current(plt)
# note: lets ignore the show param and effectively use the semicolon at the end of the REPL statement
# # do we want to show it?
# if haskey(d, :show) && d[:show]
if get(d, :show, default(:show))
# do we want to force display?
if plt[:show]
gui()
end
+468
View File
@@ -0,0 +1,468 @@
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
precompile(Plots.py_add_series, (Plots.Plot{Plots.PyPlotBackend}, Plots.Series,))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Float64, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Base.StepRange{Int64, Int64},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Function,))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Plots.OHLC, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Float64, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Base.LinSpace{Float64},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, DataFrames.DataFrame,))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Int64, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Union{UTF8String, ASCIIString}, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Function, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{ASCIIString, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Base.FloatRange{Float64},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any},))
precompile(Plots._plot!, (Plots.Plot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any}, Array{Float64, 1},))
precompile(Plots._plot!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Array{Float64, 2},))
precompile(Plots._add_defaults!, (Base.Dict{Symbol, Any}, Plots.Plot{Plots.UnicodePlotsBackend}, Plots.Subplot{Plots.UnicodePlotsBackend}, Int64,))
precompile(Plots._before_layout_calcs, (Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots._apply_series_recipe, (Plots.Plot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any},))
precompile(Plots._add_defaults!, (Base.Dict{Symbol, Any}, Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend}, Int64,))
precompile(Plots._apply_series_recipe, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any},))
precompile(Plots.setup_ijulia, ())
precompile(Plots.call, (Type{Plots.Plot{Plots.UnicodePlotsBackend}}, Plots.UnicodePlotsBackend, Int64, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Array{Plots.Series, 1}, Void, Array{Plots.Subplot, 1}, Base.Dict{Any, Plots.Subplot}, Plots.EmptyLayout, Array{Plots.Subplot, 1}, Bool,))
precompile(Plots.expand_extrema!, (Plots.Subplot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any},))
precompile(Plots.create_grid_vcat, (Expr,))
precompile(Plots.expand_extrema!, (Plots.Subplot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any},))
precompile(Plots.update_child_bboxes!, (Plots.GridLayout, Array{Measures.Length{:mm, Float64}, 1},))
precompile(Plots.preprocessArgs!, (Base.Dict{Symbol, Any},))
precompile(Plots.call, (Type{Plots.Plot{Plots.PyPlotBackend}}, Plots.PyPlotBackend, Int64, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Array{Plots.Series, 1}, Void, Array{Plots.Subplot, 1}, Base.Dict{Any, Plots.Subplot}, Plots.EmptyLayout, Array{Plots.Subplot, 1}, Bool,))
precompile(Plots.fix_xy_lengths!, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any},))
precompile(Plots._update_min_padding!, (Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.warnOnUnsupported_args, (Plots.PyPlotBackend, Base.Dict{Symbol, Any},))
precompile(Plots.build_layout, (Plots.GridLayout, Int64,))
precompile(Plots.build_layout, (Plots.GridLayout, Int64, Array{Plots.Plot, 1},))
precompile(Plots.warnOnUnsupported, (Plots.UnicodePlotsBackend, Base.Dict{Symbol, Any},))
precompile(Plots.link_axes!, (Plots.GridLayout, Symbol,))
precompile(Plots.warnOnUnsupported, (Plots.PyPlotBackend, Base.Dict{Symbol, Any},))
precompile(Plots._update_plot_args, (Plots.Plot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any},))
precompile(Plots.font, (Int64,))
precompile(Plots.recompute_lengths, (Array{Measures.Measure, 1},))
precompile(Plots._update_plot_object, (Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.font, (Symbol,))
precompile(Plots.create_grid, (Expr,))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Void, Int64,))
precompile(Plots.pickDefaultBackend, ())
precompile(Plots.default_should_widen, (Plots.Axis,))
precompile(Plots.setup_atom, ())
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Symbol, Int64,))
precompile(Plots.my_hist_2d, (Array{Any, 1}, Array{Float64, 1}, Array{Float64, 1}, Int64,))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, ASCIIString, Int64,))
precompile(Plots.create_grid_curly, (Expr,))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Bool, Int64,))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Int64,))
precompile(Plots.my_hist, (Array{Any, 1}, Array{Float64, 1}, Int64,))
precompile(Plots.getpctrange, (Int64,))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{Symbol, 1},))
precompile(Plots.default, (Symbol,))
precompile(Plots.process_axis_arg!, (Base.Dict{Symbol, Any}, Symbol, Symbol,))
precompile(Plots.pie_labels, (Plots.Subplot{Plots.PyPlotBackend}, Plots.Series,))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Measures.Length{:mm, Float64}, Int64,))
precompile(Plots.py_path, (Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots._update_min_padding!, (Plots.GridLayout,))
precompile(Plots.warnOnUnsupported_scales, (Plots.UnicodePlotsBackend, Base.Dict{Symbol, Any},))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Plots.Font, Int64,))
precompile(Plots.process_axis_arg!, (Base.Dict{Symbol, Any}, Tuple{Int64, Int64}, Symbol,))
precompile(Plots.slice_arg!, (Array{Any, 1}, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Array{Any, 1}, Int64,))
precompile(Plots.default, (Symbol, Tuple{Int64, Int64},))
precompile(Plots.warnOnUnsupported_scales, (Plots.PyPlotBackend, Base.Dict{Symbol, Any},))
precompile(Plots.axis_limits, (Plots.Axis, Bool,))
precompile(Plots.default, (Symbol, Bool,))
precompile(Plots.getColorZ, (Plots.ColorGradient, Float64,))
precompile(Plots._update_plot_args, (Plots.Plot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any},))
precompile(Plots.call, (Type{Plots.Surface}, Function, Base.FloatRange{Float64}, Base.FloatRange{Float64},))
precompile(Plots.font, (Symbol,))
precompile(Plots.process_axis_arg!, (Base.Dict{Symbol, Any}, Base.StepRange{Int64, Int64}, Symbol,))
precompile(Plots.call, (Array{Any, 1}, Type{Plots.Subplot}, Plots.UnicodePlotsBackend,))
precompile(Plots.extractGroupArgs, (Array{ASCIIString, 1}, Array{Float64, 1},))
precompile(Plots._update_subplot_args, (Array{Any, 1}, Plots.Plot{Plots.UnicodePlotsBackend}, Plots.Subplot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.call, (Array{Any, 1}, Type{Plots.Subplot}, Plots.PyPlotBackend,))
precompile(Plots._update_subplot_args, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.extractGroupArgs, (Array{Union{UTF8String, ASCIIString}, 1},))
precompile(Plots.bbox_to_pcts, (Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Bool,))
precompile(Plots.plot, (Array{Any, 1}, Array{Float64, 1},))
precompile(Plots.py_marker, (Plots.Shape,))
precompile(Plots.getindex, (Plots.Subplot{Plots.UnicodePlotsBackend}, Symbol,))
precompile(Plots.getindex, (Plots.Subplot{Plots.PyPlotBackend}, Symbol,))
precompile(Plots.discrete_value!, (Plots.Axis, Array{Union{UTF8String, ASCIIString}, 1},))
precompile(Plots.prepare_output, (Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.update_inset_bboxes!, (Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.add_layout_pct!, (Base.Dict{Symbol, Any}, Expr, Int64, Int64,))
precompile(Plots.process_axis_arg!, (Base.Dict{Symbol, Any}, ASCIIString, Symbol,))
precompile(Plots.call, (Type{Plots.Shape}, Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots.plot, (Array{Any, 1}, Base.LinSpace{Float64}, Array{Float64, 2},))
precompile(Plots.call, (Array{Any, 1}, Type{Plots.EmptyLayout}, Plots.RootLayout,))
precompile(Plots.plot, (Array{Any, 1}, Function, Function,))
precompile(Plots.should_add_to_legend, (Plots.Series,))
precompile(Plots.plot, (Array{Any, 1}, DataFrames.DataFrame, Symbol,))
precompile(Plots.plot, (Array{Any, 1}, Array{Plots.OHLC, 1},))
precompile(Plots.convertToAnyVector, (Array{Float64, 2}, Base.Dict{Symbol, Any},))
precompile(Plots.plot, (Array{Any, 1}, Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots.plot, (Array{Any, 1}, Array{ASCIIString, 1}, Array{Float64, 1},))
precompile(Plots.plot!, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend}, Array{Float64, 1},))
precompile(Plots.processLineArg, (Base.Dict{Symbol, Any}, Symbol,))
precompile(Plots.aliasesAndAutopick, (Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any}, Array{Symbol, 1}, Int64,))
precompile(Plots.plot!, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend}, Array{Int64, 1},))
precompile(Plots.pie, (Array{Any, 1}, Array{ASCIIString, 1},))
precompile(Plots.aliasesAndAutopick, (Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any}, Array{Any, 1}, Int64,))
precompile(Plots.merge_with_base_supported, (Array{Symbol, 1},))
precompile(Plots.histogram2d, (Array{Any, 1}, Array{Float64, 1},))
precompile(Plots.plot, (Array{Any, 1}, Base.StepRange{Int64, Int64}, Array{Float64, 2},))
precompile(Plots.plot, (Array{Any, 1}, Base.LinSpace{Float64}, Array{Float64, 1},))
precompile(Plots.plot, (Array{Any, 1}, Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots.font, ())
precompile(Plots.plot, (Array{Any, 1}, Base.FloatRange{Float64}, Array{Float64, 1},))
precompile(Plots.plot, (Array{Any, 1}, Base.FloatRange{Float64}, Base.FloatRange{Float64},))
precompile(Plots.plot, (Array{Any, 1}, Array{Function, 1}, Array{Float64, 1},))
precompile(Plots.scatter, (Array{Any, 1}, Base.LinSpace{Float64},))
precompile(Plots.plot!, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend}, Base.LinSpace{Float64},))
precompile(Plots.plot!, (Array{Any, 1}, Base.LinSpace{Float64}, Array{Float64, 1},))
precompile(Plots.get_zvalues, (Int64,))
precompile(Plots.plot, (Array{Any, 1}, Array{Union{UTF8String, ASCIIString}, 1}, Array{Union{UTF8String, ASCIIString}, 1},))
precompile(Plots.histogram, (Array{Any, 1}, Array{Float64, 1},))
precompile(Plots.hline!, (Array{Any, 1}, Array{Float64, 2},))
precompile(Plots.layout_args, (Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.heatmap, (Array{Any, 1}, Array{Union{UTF8String, ASCIIString}, 1},))
precompile(Plots._replace_linewidth, (Base.Dict{Symbol, Any},))
precompile(Plots.plot!, (Array{Any, 1}, Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots.plot!, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend}, Array{Float64, 2},))
precompile(Plots.py_markercolor, (Base.Dict{Symbol, Any},))
precompile(Plots.unzip, (Array{Tuple{Float64, Float64}, 1},))
precompile(Plots.link_axes!, (Array{Plots.AbstractLayout, 2}, Symbol,))
precompile(Plots.plot!, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend}, Array{Float64, 1},))
precompile(Plots.contour, (Array{Any, 1}, Base.FloatRange{Float64},))
precompile(Plots.scatter, (Array{Any, 1}, DataFrames.DataFrame,))
precompile(Plots.scatter!, (Array{Any, 1}, Base.LinSpace{Float64},))
precompile(Plots.scatter!, (Array{Any, 1}, Array{Float64, 1},))
precompile(Plots.getxy, (Plots.Plot{Plots.PyPlotBackend}, Int64,))
precompile(Plots.plot, (Array{Any, 1}, Array{Float64, 2},))
precompile(Plots.get_xy, (Array{Plots.OHLC, 1}, Base.UnitRange{Int64},))
precompile(Plots.convertToAnyVector, (Array{Function, 1}, Base.Dict{Symbol, Any},))
precompile(Plots.py_add_annotations, (Plots.Subplot{Plots.PyPlotBackend}, Int64, Float64, Plots.PlotText,))
precompile(Plots.plot!, (Array{Any, 1}, Array{Float64, 1},))
precompile(Plots.get_color_palette, (Symbol, ColorTypes.RGB{Float64}, Int64,))
precompile(Plots.py_add_annotations, (Plots.Subplot{Plots.PyPlotBackend}, Float64, Float64, Plots.PlotText,))
precompile(Plots.py_colormap, (Plots.ColorGradient, Float64,))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, Plots.Stroke,))
precompile(Plots.call, (Type{Plots.ColorVector}, Array{Symbol, 1},))
precompile(Plots.py_colormap, (Plots.ColorGradient, Void,))
precompile(Plots.py_fillcolor, (Base.Dict{Symbol, Any},))
precompile(Plots.processLineArg, (Base.Dict{Symbol, Any}, Float64,))
precompile(Plots.plot!, (Array{Any, 1}, Array{Float64, 2},))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, Symbol,))
precompile(Plots.call, (Type{Plots.Plot},))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{ColorTypes.RGBA{Float64}, 1},))
precompile(Plots.plot!, (Array{Any, 1}, Array{Int64, 1},))
precompile(Plots.getExtension, (UTF8String,))
precompile(Plots.call, (Array{Any, 1}, Type{Plots.EmptyLayout},))
precompile(Plots.update!, (Array{Any, 1}, Plots.Axis,))
precompile(Plots.frame, (Plots.Animation, Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.link_axes!, (Array{Plots.AbstractLayout, 1}, Symbol,))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{ColorTypes.RGB{Float64}, 1},))
precompile(Plots.fakedata, (Int64,))
precompile(Plots.plot!, (Array{Any, 1}, Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.py_compute_axis_minval, (Plots.Axis,))
precompile(Plots.processLineArg, (Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.command_idx, (Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any},))
precompile(Plots.getindex, (Plots.Axis, Symbol,))
precompile(Plots.__init__, ())
precompile(Plots.isvertical, (Base.Dict{Symbol, Any},))
precompile(Plots.getExtension, (ASCIIString,))
precompile(Plots.py_marker, (Symbol,))
precompile(Plots.py_init_subplot, (Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64},))
precompile(Plots.bucket_index, (Float64, Base.LinSpace{Float64},))
precompile(Plots.default, (Array{Any, 1},))
precompile(Plots.filter_data!, (Base.Dict{Symbol, Any}, Array{Int64, 1},))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{Symbol, 1}, Base.LinSpace{Float64},))
precompile(Plots.slice_arg, (Array{Symbol, 2}, Int64,))
precompile(Plots.getindex, (Plots.Plot{Plots.UnicodePlotsBackend}, Symbol,))
precompile(Plots.plot!, (Array{Any, 1},))
precompile(Plots.push!, (Plots.Plot{Plots.PyPlotBackend}, Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, Float64,))
precompile(Plots.expand_extrema!, (Plots.Axis, Base.FloatRange{Float64},))
precompile(Plots.getindex, (Plots.Plot{Plots.PyPlotBackend}, Symbol,))
precompile(Plots.handle_dfs, (DataFrames.DataFrame, Base.Dict{Symbol, Any}, ASCIIString, Symbol,))
precompile(Plots.filter_data, (Base.UnitRange{Int64}, Array{Int64, 1},))
precompile(Plots.call, (Type{Plots.ColorWrapper}, ColorTypes.RGBA{Float64},))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, Array{Symbol, 2},))
precompile(Plots.processLineArg, (Base.Dict{Symbol, Any}, Array{Symbol, 2},))
precompile(Plots.color_or_nothing!, (Base.Dict{Symbol, Any}, Symbol,))
precompile(Plots.processMarkerArg, (Base.Dict{Symbol, Any}, Plots.Shape,))
precompile(Plots.py_fillcolormap, (Base.Dict{Symbol, Any},))
precompile(Plots.transpose_z, (Base.Dict{Symbol, Any}, Array{Float64, 2}, Bool,))
precompile(Plots.py_linecolor, (Base.Dict{Symbol, Any},))
precompile(Plots.call, (Type{Plots.OHLC}, Float64, Float64, Float64, Float64,))
precompile(Plots.setxy!, (Plots.Plot{Plots.PyPlotBackend}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64,))
precompile(Plots.push!, (Plots.Segments, Float64, Float64, Float64, Float64,))
precompile(Plots.handle_group, (DataFrames.DataFrame, Base.Dict{Symbol, Any},))
precompile(Plots.lightness_from_background, (ColorTypes.RGB{Float64},))
precompile(Plots.expand_extrema!, (Plots.Axis, Base.LinSpace{Float64},))
precompile(Plots.py_bbox, (Array{Any, 1},))
precompile(Plots.py_markerstrokecolor, (Base.Dict{Symbol, Any},))
precompile(Plots.arrow, ())
precompile(Plots.convert, (Type{Array{Float64, 1}}, Base.StepRange{Int64, Int64},))
precompile(Plots.expand_extrema!, (Plots.Axis, Array{Float64, 1},))
precompile(Plots.convertLegendValue, (Symbol,))
precompile(Plots.slice_arg, (Array{Measures.Length{:mm, Float64}, 2}, Int64,))
precompile(Plots.calc_num_subplots, (Plots.GridLayout,))
precompile(Plots.processFillArg, (Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.slice_arg, (Array{Plots.ColorWrapper, 2}, Int64,))
precompile(Plots.slice_arg, (Array{ASCIIString, 2}, Int64,))
precompile(Plots.filter_data, (Array{Float64, 1}, Array{Int64, 1},))
precompile(Plots.py_linecolormap, (Base.Dict{Symbol, Any},))
precompile(Plots.discrete_value!, (Plots.Axis, ASCIIString,))
precompile(Plots.allShapes, (ColorTypes.RGBA{Float64},))
precompile(Plots.expand_extrema!, (Plots.Axis, Array{Int64, 1},))
precompile(Plots.py_color_fix, (Tuple{Float64, Float64, Float64, Float64}, Base.LinSpace{Float64},))
precompile(Plots.discrete_value!, (Plots.Axis, Symbol,))
precompile(Plots.push!, (Plots.Segments, Float64, Int64, Int64, Float64,))
precompile(Plots.expand_extrema!, (Plots.Axis, Plots.Surface{Array{Float64, 2}},))
precompile(Plots.heatmap_edges, (Array{Float64, 1},))
precompile(Plots.expand_extrema!, (Plots.Axis, Base.StepRange{Int64, Int64},))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Plots.Shape, Symbol,))
precompile(Plots.py_color, (Plots.ColorWrapper, Float64,))
precompile(Plots.call, (Type{Plots.GridLayout}, Int64, Int64,))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}, Symbol,))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Bool, Symbol,))
precompile(Plots.hvline_limits, (Plots.Axis,))
precompile(Plots.current, ())
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Float64, Symbol,))
precompile(Plots.compute_gridsize, (Int64, Int64, Int64,))
precompile(Plots.py_color, (ColorTypes.RGB{Float64}, Void,))
precompile(Plots.interpolate_rgb, (ColorTypes.RGBA{Float64}, ColorTypes.RGBA{Float64}, Float64,))
precompile(Plots.expand_extrema!, (Plots.Axis, Base.UnitRange{Int64},))
precompile(Plots.allShapes, (Float64,))
precompile(Plots.warn_on_deprecated_backend, (Symbol,))
precompile(Plots.py_color_fix, (Tuple{Float64, Float64, Float64, Float64}, Array{Int64, 1},))
precompile(Plots.setindex!, (Plots.GridLayout, Plots.EmptyLayout, Int64, Int64,))
precompile(Plots.expand_extrema!, (Plots.Axis, Tuple{Int64, Int64},))
precompile(Plots.allShapes, (Int64,))
precompile(Plots.py_markercolormap, (Base.Dict{Symbol, Any},))
precompile(Plots.interpolate_rgb, (ColorTypes.RGB{Float64}, ColorTypes.RGB{Float64}, Float64,))
precompile(Plots.get_ticks, (Plots.Axis,))
precompile(Plots.backend, ())
precompile(Plots.get_xy, (Plots.OHLC{Float64}, Int64, Float64,))
precompile(Plots.allShapes, (Plots.Stroke,))
precompile(Plots.replaceAliases!, (Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any},))
precompile(Plots._create_backend_figure, (Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.png, (Plots.Plot{Plots.PyPlotBackend}, UTF8String,))
precompile(Plots.processFillArg, (Base.Dict{Symbol, Any}, Symbol,))
precompile(Plots.allShapes, (Plots.Shape,))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Plots.Stroke, Symbol,))
precompile(Plots.py_color_fix, (Tuple{Float64, Float64, Float64, Float64}, Array{Float64, 1},))
precompile(Plots.plot, (Array{Float64, 1},))
precompile(Plots.rowsize, (Expr,))
precompile(Plots.get_axis, (Plots.Subplot{Plots.PyPlotBackend}, Symbol,))
precompile(Plots.png, (Plots.Plot{Plots.PyPlotBackend}, ASCIIString,))
precompile(Plots.expand_extrema!, (Plots.Axis, Tuple{Float64, Float64},))
precompile(Plots._markershape_supported, (Plots.PyPlotBackend, Plots.Shape,))
precompile(Plots.processFillArg, (Base.Dict{Symbol, Any}, Bool,))
precompile(Plots.supported_types, (Plots.PyPlotBackend,))
precompile(Plots.get_axis, (Plots.Subplot{Plots.UnicodePlotsBackend}, Symbol,))
precompile(Plots.setindex!, (Plots.GridLayout, Plots.GridLayout, Int64, Int64,))
precompile(Plots.plot, ())
precompile(Plots.py_color_fix, (Tuple{Float64, Float64, Float64, Float64}, Base.FloatRange{Float64},))
precompile(Plots._markershape_supported, (Plots.PyPlotBackend, Symbol,))
precompile(Plots.ok, (Float64, Float64, Int64,))
precompile(Plots.allShapes, (Symbol,))
precompile(Plots._initialize_backend, (Plots.PyPlotBackend,))
precompile(Plots.plot, (Plots.Plot{Plots.PyPlotBackend}, Plots.Plot{Plots.PyPlotBackend},))
precompile(Plots.bar, (Array{Float64, 1},))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{ColorTypes.RGBA{Float64}, 1}, Base.LinSpace{Float64},))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Int64, Symbol,))
precompile(Plots.nanappend!, (Array{Float64, 1}, Array{Float64, 1},))
precompile(Plots.autopick, (Array{ColorTypes.RGBA, 1}, Int64,))
precompile(Plots.compute_xyz, (Void, Array{Int64, 1}, Void,))
precompile(Plots._add_markershape, (Base.Dict{Symbol, Any},))
precompile(Plots._backend_instance, (Symbol,))
precompile(Plots.py_color, (ColorTypes.RGBA{Float64}, Float64,))
precompile(Plots.update_child_bboxes!, (Plots.GridLayout,))
precompile(Plots._replace_markershape, (Symbol,))
precompile(Plots.has_black_border_for_default, (Symbol,))
precompile(Plots._filter_input_data!, (Base.Dict{Symbol, Any},))
precompile(Plots.compute_xyz, (Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64},))
precompile(Plots.text, (ASCIIString, Int64, Symbol,))
precompile(Plots.allShapes, (Array{Symbol, 2},))
precompile(Plots.py_color_fix, (Tuple{Float64, Float64, Float64, Float64}, Base.UnitRange{Int64},))
precompile(Plots.replaceAlias!, (Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any},))
precompile(Plots.compute_xyz, (Array{ASCIIString, 1}, Array{Float64, 1}, Void,))
precompile(Plots.layout_args, (Int64,))
precompile(Plots.text, (ASCIIString, Symbol, Int64,))
precompile(Plots.compute_xyz, (Base.FloatRange{Float64}, Base.FloatRange{Float64}, Plots.Surface{Array{Float64, 2}},))
precompile(Plots.all3D, (Base.Dict{Symbol, Any},))
precompile(Plots.cycle, (Array{Plots.Subplot, 1}, Int64,))
precompile(Plots.compute_xyz, (Base.StepRange{Int64, Int64}, Array{Float64, 1}, Void,))
precompile(Plots.plotarea!, (Plots.Subplot{Plots.PyPlotBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.like_surface, (Symbol,))
precompile(Plots.build_layout, (Base.Dict{Symbol, Any},))
precompile(Plots.compute_xyz, (Array{Union{UTF8String, ASCIIString}, 1}, Array{Union{UTF8String, ASCIIString}, 1}, Plots.Surface{Array{Float64, 2}},))
precompile(Plots.py_linestyle, (Symbol, Symbol,))
precompile(Plots.plot!, (Array{Float64, 2},))
precompile(Plots.plot!, (Plots.Plot{Plots.PyPlotBackend}, Array{Float64, 2},))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{ColorTypes.RGB{Float64}, 1}, Base.LinSpace{Float64},))
precompile(Plots.py_color, (ColorTypes.RGBA{Float64}, Void,))
precompile(Plots.yaxis!, (ASCIIString, Symbol,))
precompile(Plots.compute_xyz, (Base.LinSpace{Float64}, Array{Float64, 1}, Void,))
precompile(Plots.isijulia, ())
precompile(Plots.addExtension, (UTF8String, ASCIIString,))
precompile(Plots.call, (Type{Plots.ColorGradient}, Array{ColorTypes.RGBA{Float64}, 1}, Array{Float64, 1},))
precompile(Plots.expand_extrema!, (Plots.Subplot{Plots.PyPlotBackend}, Float64, Float64, Float64, Float64,))
precompile(Plots.plotarea!, (Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.layout_args, (Base.Dict{Symbol, Any},))
precompile(Plots.compute_xyz, (Base.FloatRange{Float64}, Array{Float64, 1}, Void,))
precompile(Plots.addExtension, (ASCIIString, ASCIIString,))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Symbol, Symbol,))
precompile(Plots._initialize_backend, (Plots.PlotlyBackend,))
precompile(Plots.push!, (Plots.Plot{Plots.PyPlotBackend}, Int64, Float64, Float64,))
precompile(Plots.bbox!, (Plots.Subplot{Plots.PyPlotBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.vline!, (Array{Int64, 1},))
precompile(Plots.supported_markers, (Plots.PyPlotBackend,))
precompile(Plots.bbox!, (Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.stroke, (Int64,))
precompile(Plots.compute_xyz, (Array{Float64, 1}, Array{Float64, 1}, Void,))
precompile(Plots.right, (Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.extractGroupArgs, (Symbol, DataFrames.DataFrame, Symbol,))
precompile(Plots.generate_colorgradient, (ColorTypes.RGB{Float64},))
precompile(Plots.expand_extrema!, (Plots.Extrema, Bool,))
precompile(Plots.py_colormap, (Plots.ColorWrapper, Void,))
precompile(Plots.expand_extrema!, (Plots.Extrema, Float64,))
precompile(Plots.contour, (Base.FloatRange{Float64},))
precompile(Plots.bottom, (Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.text, (ASCIIString, Symbol,))
precompile(Plots.create_grid, (Symbol,))
precompile(Plots.expand_extrema!, (Plots.Axis, Bool,))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol,))
precompile(Plots.convertToAnyVector, (Void, Base.Dict{Symbol, Any},))
precompile(Plots.py_dpi_scale, (Plots.Plot{Plots.PyPlotBackend}, Int64,))
precompile(Plots.png, (ASCIIString,))
precompile(Plots.supported_scales, (Plots.PyPlotBackend,))
precompile(Plots.convertColor, (ColorTypes.RGBA{Float64}, Float64,))
precompile(Plots.extendSeriesData, (Array{Float64, 1}, Float64,))
precompile(Plots.compute_xyz, (Void, Array{Float64, 1}, Void,))
precompile(Plots.py_color, (Symbol,))
precompile(Plots.expand_extrema!, (Plots.Extrema, Int64,))
precompile(Plots.supported_styles, (Plots.PyPlotBackend,))
precompile(Plots._initialize_backend, (Plots.UnicodePlotsBackend,))
precompile(Plots._initialize_backend, (Plots.GRBackend,))
precompile(Plots.is3d, (Symbol,))
precompile(Plots.supported_types, (Plots.UnicodePlotsBackend,))
precompile(Plots.compute_xyz, (Array{Float64, 1}, Function, Void,))
precompile(Plots.py_color, (Symbol, Void,))
precompile(Plots.trueOrAllTrue, (Function, Array{Symbol, 2},))
precompile(Plots.typemin, (Measures.Length{:mm, Float64},))
precompile(Plots.expand_extrema!, (Plots.Axis, Float64,))
precompile(Plots.get_subplot_index, (Plots.Plot{Plots.UnicodePlotsBackend}, Plots.Subplot{Plots.UnicodePlotsBackend},))
precompile(Plots.leftpad, (Plots.GridLayout,))
precompile(Plots._update_subplot_args, (Plots.Plot{Plots.UnicodePlotsBackend}, Plots.Subplot{Plots.UnicodePlotsBackend}, Base.Dict{Symbol, Any}, Int64,))
precompile(Plots.centers, (Base.LinSpace{Float64},))
precompile(Plots.expand_extrema!, (Plots.Axis, Int64,))
precompile(Plots.text, (ASCIIString,))
precompile(Plots.convertColor, (ColorTypes.RGB{Float64},))
precompile(Plots.py_color, (Plots.ColorWrapper, Void,))
precompile(Plots.py_color, (Plots.ColorWrapper,))
precompile(Plots.trueOrAllTrue, (Function, Int64,))
precompile(Plots.convertColor, (ColorTypes.RGBA{Float64},))
precompile(Plots.extrema, (Plots.Axis,))
precompile(Plots.top, (Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.convertColor, (Symbol,))
precompile(Plots.size, (Plots.Surface{Array{Float64, 2}},))
precompile(Plots.isdark, (ColorTypes.RGB{Float64},))
precompile(Plots.rowsize, (Symbol,))
precompile(Plots.series_list, (Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.convertToAnyVector, (Array{Float64, 1}, Base.Dict{Symbol, Any},))
precompile(Plots.update!, (Plots.Axis,))
precompile(Plots.push!, (Plots.Plot{Plots.PyPlotBackend}, Float64, Array{Float64, 1},))
precompile(Plots.wraptuple, (Bool,))
precompile(Plots.call, (Type{Plots.Shape}, Array{Tuple{Float64, Float64}, 1},))
precompile(Plots.slice_arg, (Base.StepRange{Int64, Int64}, Int64,))
precompile(Plots.sticks_fillfrom, (Void, Int64,))
precompile(Plots.left, (Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}},))
precompile(Plots.gr, ())
precompile(Plots.leftpad, (Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.supported_markers, ())
precompile(Plots.colorscheme, (Symbol,))
precompile(Plots.convertColor, (ColorTypes.RGB{Float64}, Void,))
precompile(Plots.isscalar, (Int64,))
precompile(Plots.wraptuple, (Int64,))
precompile(Plots.call, (Type{Plots.Plot}, Plots.UnicodePlotsBackend, Int64, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Array{Plots.Series, 1}, Void, Array{Plots.Subplot, 1}, Base.Dict{Any, Plots.Subplot}, Plots.EmptyLayout, Array{Plots.Subplot, 1}, Bool,))
precompile(Plots.supported_styles, ())
precompile(Plots.frame, (Plots.Animation,))
precompile(Plots.toppad, (Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.link_axes!, (Plots.Subplot{Plots.UnicodePlotsBackend}, Symbol,))
precompile(Plots.convertLegendValue, (Bool,))
precompile(Plots.convertColor, (ColorTypes.RGBA{Float64}, Void,))
precompile(Plots.plotly, ())
precompile(Plots.ispositive, (Measures.Length{:mm, Float64},))
precompile(Plots.rightpad, (Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.call, (Type{Plots.GroupBy}, Array{ASCIIString, 1}, Array{Array{Int64, 1}, 1},))
precompile(Plots.px2inch, (Int64,))
precompile(Plots.slice_arg, (Tuple{Int64, Int64}, Int64,))
precompile(Plots.call, (Type{Plots.UnicodePlotsBackend},))
precompile(Plots.trueOrAllTrue, (Function, Symbol,))
precompile(Plots.bottompad, (Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.annotate!, (Array{Tuple{Int64, Float64, Plots.PlotText}, 1},))
precompile(Plots.get_subplot_index, (Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.call, (Type{Plots.Plot}, Plots.PyPlotBackend, Int64, Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Array{Plots.Series, 1}, Void, Array{Plots.Subplot, 1}, Base.Dict{Any, Plots.Subplot}, Plots.EmptyLayout, Array{Plots.Subplot, 1}, Bool,))
precompile(Plots.title!, (ASCIIString,))
precompile(Plots.slice_arg, (Bool, Int64,))
precompile(Plots.wraptuple, (Float64,))
precompile(Plots.bottompad, (Plots.GridLayout,))
precompile(Plots.py_stepstyle, (Symbol,))
precompile(Plots.link_axes!, (Plots.Subplot{Plots.PyPlotBackend}, Symbol,))
precompile(Plots.call, (Type{Plots.GRBackend},))
precompile(Plots.unicodeplots, ())
precompile(Plots.rightpad, (Plots.GridLayout,))
precompile(Plots.call, (Type{Plots.PlotlyBackend},))
precompile(Plots.py_color, (ColorTypes.RGBA{Float64},))
precompile(Plots.toppad, (Plots.GridLayout,))
precompile(Plots.calc_edges, (Array{Float64, 1}, Int64,))
precompile(Plots.colorscheme, (ColorTypes.RGBA{Float64},))
precompile(Plots.slice_arg, (Int64, Int64,))
precompile(Plots.pyplot, ())
precompile(Plots._update_subplot_args, (Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend}, Base.Dict{Symbol, Any}, Int64,))
precompile(Plots._series_added, (Plots.Plot{Plots.PyPlotBackend}, Plots.Series,))
precompile(Plots.get_color_palette, (Array{ColorTypes.RGBA, 1}, ColorTypes.RGB{Float64}, Int64,))
precompile(Plots._initialize_subplot, (Plots.Plot{Plots.UnicodePlotsBackend}, Plots.Subplot{Plots.UnicodePlotsBackend},))
precompile(Plots.slice_arg, (Void, Int64,))
precompile(Plots.cycle, (Int64, Int64,))
precompile(Plots._initialize_subplot, (Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.call, (Type{Plots.PyPlotBackend},))
precompile(Plots.update_child_bboxes!, (Plots.Subplot{Plots.PyPlotBackend}, Array{Measures.Length{:mm, Float64}, 1},))
precompile(Plots.filter_data, (Void, Array{Int64, 1},))
precompile(Plots.slice_arg, (Symbol, Int64,))
precompile(Plots.slice_arg, (ASCIIString, Int64,))
precompile(Plots.layout_args, (Plots.GridLayout,))
precompile(Plots.wraptuple, (Tuple{},))
precompile(Plots.calc_num_subplots, (Plots.EmptyLayout,))
precompile(Plots.wraptuple, (Tuple{Symbol, Float64, Plots.Stroke},))
precompile(Plots.wraptuple, (Tuple{ASCIIString, Tuple{Int64, Int64}, Base.StepRange{Int64, Int64}, Symbol},))
precompile(Plots.wraptuple, (Tuple{Int64, Symbol, Float64, Array{Symbol, 2}},))
precompile(Plots.wraptuple, (Tuple{Int64, Array{Symbol, 2}},))
precompile(Plots.wraptuple, (Tuple{ASCIIString, Symbol},))
precompile(Plots._replace_markershape, (Array{Symbol, 2},))
precompile(Plots.wraptuple, (Tuple{Symbol, Int64},))
precompile(Plots.wraptuple, (Tuple{Array{Symbol, 2}, Int64},))
precompile(Plots.wraptuple, (Tuple{Int64, Symbol, Symbol},))
precompile(Plots.wraptuple, (Tuple{Int64, Float64, Symbol, Plots.Stroke},))
precompile(Plots.wraptuple, (Tuple{Float64, Array{Symbol, 2}, Int64},))
precompile(Plots.py_color, (ColorTypes.RGB{Float64},))
precompile(Plots.wraptuple, (Tuple{Int64, Float64, Symbol},))
precompile(Plots.tovec, (Array{Float64, 1},))
precompile(Plots.get_subplot, (Plots.Plot{Plots.PyPlotBackend}, Plots.Subplot{Plots.PyPlotBackend},))
precompile(Plots.eltype, (Plots.Surface{Array{Float64, 2}},))
precompile(Plots.nobigs, (Array{Float64, 1},))
precompile(Plots.get_subplot, (Plots.Plot{Plots.UnicodePlotsBackend}, Plots.Subplot{Plots.UnicodePlotsBackend},))
precompile(Plots.annotations, (Array{Any, 1},))
precompile(Plots.wraptuple, (Tuple{Int64, Symbol},))
precompile(Plots.colorscheme, (Plots.ColorWrapper,))
precompile(Plots.colorscheme, (Plots.ColorGradient,))
precompile(Plots.text, (Plots.PlotText,))
precompile(Plots._replace_markershape, (Plots.Shape,))
precompile(Plots.wraptuple, (Tuple{Array{Symbol, 2}, Int64, Float64, Plots.Stroke},))
precompile(Plots.wraptuple, (Tuple{Plots.Shape, Int64, ColorTypes.RGBA{Float64}},))
end
+99 -307
View File
@@ -98,19 +98,21 @@ end
# ----------------------------------------------------------------------------------
abstract PlotRecipe
# abstract PlotRecipe
getRecipeXY(recipe::PlotRecipe) = Float64[], Float64[]
getRecipeArgs(recipe::PlotRecipe) = ()
# getRecipeXY(recipe::PlotRecipe) = Float64[], Float64[]
# getRecipeArgs(recipe::PlotRecipe) = ()
plot(recipe::PlotRecipe, args...; kw...) = plot(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...)
plot!(recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...)
plot!(plt::Plot, recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...)
# plot(recipe::PlotRecipe, args...; kw...) = plot(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...)
# plot!(recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...)
# plot!(plt::Plot, recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...)
num_series(x::AMat) = size(x,2)
num_series(x) = 1
RecipesBase.apply_recipe{T}(d::KW, ::Type{T}, plt::Plot) = throw(MethodError("Unmatched plot recipe: $T"))
# # if it's not a recipe, just do nothing and return the args
# function RecipesBase.apply_recipe(d::KW, args...; issubplot=false)
# if issubplot && !isempty(args) && !haskey(d, :n) && !haskey(d, :layout)
@@ -214,8 +216,20 @@ end
# end
# @deps sticks path
function hvline_limits(axis::Axis)
vmin, vmax = axis_limits(axis)
if vmin >= vmax
if isfinite(vmin)
vmax = vmin + 1
else
vmin, vmax = 0.0, 1.1
end
end
vmin, vmax
end
@recipe function f(::Type{Val{:hline}}, x, y, z)
xmin, xmax = axis_limits(d[:subplot][:xaxis])
xmin, xmax = hvline_limits(d[:subplot][:xaxis])
n = length(y)
newx = repmat(Float64[xmin, xmax, NaN], n)
newy = vec(Float64[yi for i=1:3,yi=y])
@@ -227,7 +241,7 @@ end
@deps hline path
@recipe function f(::Type{Val{:vline}}, x, y, z)
ymin, ymax = axis_limits(d[:subplot][:yaxis])
ymin, ymax = hvline_limits(d[:subplot][:yaxis])
n = length(y)
newx = vec(Float64[yi for i=1:3,yi=y])
newy = repmat(Float64[ymin, ymax, NaN], n)
@@ -352,7 +366,7 @@ function bezier_value(pts::AVec, t::Real)
end
# create segmented bezier curves in place of line segments
@recipe function f(::Type{Val{:curves}}, x, y, z)
@recipe function f(::Type{Val{:curves}}, x, y, z; npoints = 30)
args = z != nothing ? (x,y,z) : (x,y)
newx, newy = zeros(0), zeros(0)
fr = d[:fillrange]
@@ -360,7 +374,6 @@ end
newz = z != nothing ? zeros(0) : nothing
lz = d[:line_z]
newlz = lz != nothing ? zeros(0) : nothing
npoints = pop!(d, :npoints, 30)
# for each line segment (point series with no NaNs), convert it into a bezier curve
# where the points are the control points of the curve
@@ -377,12 +390,8 @@ end
end
if lz != nothing
lzrng = cycle(lz, rng) # the line_z's for this segment
# @show lzrng, sizeof(lzrng) map(t -> 1+floor(Int, t * (length(rng)-1)), ts)
# choose the line_z value of the control point just before this t
push!(newlz, 0.0)
append!(newlz, map(t -> lzrng[1+floor(Int, t * (length(rng)-1))], ts))
# lzrng = vcat()
# nanappend!(newlz, #map(t -> bezier_value(cycle(lz,rng), t), ts))
end
end
@@ -410,6 +419,11 @@ end
# create a bar plot as a filled step function
@recipe function f(::Type{Val{:bar}}, x, y, z)
# if horizontal, switch x/y
if !isvertical(d)
x, y = y, x
end
nx, ny = length(x), length(y)
edges = if nx == ny
# x is centers, calc the edges
@@ -433,36 +447,25 @@ end
# make fillto a vector... default fills to 0
fillto = d[:fillrange]
if fillto == nothing
fillto = zeros(1)
elseif isa(fillto, Number)
fillto = Float64[fillto]
fillto = 0
end
nf = length(fillto)
npts = 3ny + 1
heights = y
x = zeros(npts)
y = zeros(npts)
fillrng = zeros(npts)
# create the path in triplets. after the first bottom-left coord of the first bar:
# add the top-left, top-right, and bottom-right coords for each height
x[1] = edges[1]
y[1] = fillto[1]
fillrng[1] = fillto[1]
# create the bar shapes by adding x/y segments
xseg, yseg = Segments(), Segments()
for i=1:ny
idx = 3i
rng = idx-1:idx+1
fi = fillto[mod1(i,nf)]
x[rng] = [edges[i], edges[i+1], edges[i+1]]
y[rng] = [heights[i], heights[i], fi]
fillrng[rng] = [fi, fi, fi]
fi = cycle(fillto,i)
push!(xseg, edges[i], edges[i], edges[i+1], edges[i+1])
push!(yseg, y[i], fi, fi, y[i])
end
x := x
y := y
fillrange := fillrng
seriestype := :path
# switch back
if !isvertical(d)
xseg, yseg = yseg, xseg
end
x := xseg.pts
y := yseg.pts
seriestype := :shape
()
end
@deps bar path
@@ -557,6 +560,7 @@ centers(v::AVec) = v[1] + cumsum(diff(v))
x := centers(xedges)
y := centers(yedges)
z := Surface(counts)
linewidth := 0
seriestype := :heatmap
()
end
@@ -585,27 +589,23 @@ const _box_halfwidth = 0.4
notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
# function apply_series_recipe(d::KW, ::Type{Val{:box}})
@recipe function f(::Type{Val{:boxplot}}, x, y, z; notch=false, range=1.5)
# Plots.dumpdict(d, "box before", true)
# create a list of shapes, where each shape is a single boxplot
shapes = Shape[]
groupby = extractGroupArgs(x)
outliers_y = Float64[]
outliers_x = Float64[]
xsegs, ysegs = Segments(), Segments()
glabels = sort(collect(unique(x)))
warning = false
outliers_x, outliers_y = zeros(0), zeros(0)
for glabel in glabels
# filter y
values = y[filter(i -> cycle(x,i) == glabel, 1:length(y))]
for (i, glabel) in enumerate(groupby.groupLabels)
# filter y values
values = d[:y][groupby.groupIds[i]]
# then compute quantiles
# compute quantiles
q1,q2,q3,q4,q5 = quantile(values, linspace(0,1,5))
# notch
n = notch_width(q2, q4, length(values))
# warn on inverted notches?
if notch && !warning && ( (q2>(q3-n)) || (q4<(q3+n)) )
warn("Boxplot's notch went outside hinges. Set notch to false.")
warning = true # Show the warning only one time
@@ -614,8 +614,10 @@ notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
# make the shape
center = discrete_value!(d[:subplot][:xaxis], glabel)[1]
l, m, r = center - _box_halfwidth, center, center + _box_halfwidth
# internal nodes for notches
L, R = center - 0.5 * _box_halfwidth, center + 0.5 * _box_halfwidth
# outliers
if Float64(range) != 0.0 # if the range is 0.0, the whiskers will extend to the data
limit = range*(q4-q2)
@@ -632,57 +634,49 @@ notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
# using maximum and minimum values inside the limits
q1, q5 = extrema(inside)
end
# Box
xcoords = notch::Bool ? [
m, l, r, m, m, NaN, # lower T
l, l, L, R, r, r, l, NaN, # lower box
l, l, L, R, r, r, l, NaN, # upper box
m, l, r, m, m, NaN, # upper T
] : [
m, l, r, m, m, NaN, # lower T
l, l, r, r, l, NaN, # lower box
l, l, r, r, l, NaN, # upper box
m, l, r, m, m, NaN, # upper T
]
ycoords = notch::Bool ? [
q1, q1, q1, q1, q2, NaN, # lower T
q2, q3-n, q3, q3, q3-n, q2, q2, NaN, # lower box
q4, q3+n, q3, q3, q3+n, q4, q4, NaN, # upper box
q5, q5, q5, q5, q4, NaN, # upper T
] : [
q1, q1, q1, q1, q2, NaN, # lower T
q2, q3, q3, q2, q2, NaN, # lower box
q4, q3, q3, q4, q4, NaN, # upper box
q5, q5, q5, q5, q4, NaN, # upper T
]
push!(shapes, Shape(xcoords, ycoords))
if notch
push!(xsegs, m, l, r, m, m) # lower T
push!(xsegs, l, l, L, R, r, r, l) # lower box
push!(xsegs, l, l, L, R, r, r, l) # upper box
push!(xsegs, m, l, r, m, m) # upper T
push!(ysegs, q1, q1, q1, q1, q2) # lower T
push!(ysegs, q2, q3-n, q3, q3, q3-n, q2, q2) # lower box
push!(ysegs, q4, q3+n, q3, q3, q3+n, q4, q4) # upper box
push!(ysegs, q5, q5, q5, q5, q4) # upper T
else
push!(xsegs, m, l, r, m, m) # lower T
push!(xsegs, l, l, r, r, l) # lower box
push!(xsegs, l, l, r, r, l) # upper box
push!(xsegs, m, l, r, m, m) # upper T
push!(ysegs, q1, q1, q1, q1, q2) # lower T
push!(ysegs, q2, q3, q3, q2, q2) # lower box
push!(ysegs, q4, q3, q3, q4, q4) # upper box
push!(ysegs, q5, q5, q5, q5, q4) # upper T
end
end
# d[:plotarg_overrides] = KW(:xticks => (1:length(shapes), groupby.groupLabels))
seriestype := :shape
# n = length(groupby.groupLabels)
# xticks --> (linspace(0.5,n-0.5,n), groupby.groupLabels)
# clean d
pop!(d, :notch)
pop!(d, :range)
# we want to set the fields directly inside series recipes... args are ignored
d[:x], d[:y] = Plots.shape_coords(shapes)
# Outliers
@series begin
seriestype := :scatter
seriestype := :scatter
markershape := :circle
x := outliers_x
y := outliers_y
label := ""
primary := false
markercolor := d[:fillcolor]
markeralpha := d[:fillalpha]
markerstrokecolor := d[:linecolor]
markerstrokealpha := d[:linealpha]
x := outliers_x
y := outliers_y
primary := false
()
end
() # expects a tuple returned
seriestype := :shape
x := xsegs.pts
y := ysegs.pts
()
end
@deps boxplot shape scatter
@@ -712,20 +706,12 @@ else
end
# function apply_series_recipe(d::KW, ::Type{Val{:violin}})
@recipe function f(::Type{Val{:violin}}, x, y, z; trim=true)
# dumpdict(d, "box before", true)
# TODO: add scatter series with outliers
# create a list of shapes, where each shape is a single boxplot
shapes = Shape[]
groupby = extractGroupArgs(d[:x])
for (i, glabel) in enumerate(groupby.groupLabels)
# get the edges and widths
y = d[:y][groupby.groupIds[i]]
widths, centers = violin_coords(y, trim=trim)
xsegs, ysegs = Segments(), Segments()
glabels = sort(collect(unique(x)))
for glabel in glabels
widths, centers = violin_coords(y[filter(i -> cycle(x,i) == glabel, 1:length(y))], trim=trim)
isempty(widths) && continue
# normalize
widths = _box_halfwidth * widths / maximum(widths)
@@ -734,18 +720,14 @@ end
xcenter = discrete_value!(d[:subplot][:xaxis], glabel)[1]
xcoords = vcat(widths, -reverse(widths)) + xcenter
ycoords = vcat(centers, reverse(centers))
push!(shapes, Shape(xcoords, ycoords))
push!(xsegs, xcoords)
push!(ysegs, ycoords)
end
# d[:plotarg_overrides] = KW(:xticks => (1:length(shapes), groupby.groupLabels))
seriestype := :shape
# n = length(groupby.groupLabels)
# xticks --> (linspace(0.5,n-0.5,n), groupby.groupLabels)
# clean up d
pop!(d, :trim)
d[:x], d[:y] = shape_coords(shapes)
x := xsegs.pts
y := ysegs.pts
()
end
@deps violin shape
@@ -761,10 +743,6 @@ end
x := newx
y := newy
seriestype := :path
# clean up d
pop!(d, :trim)
()
end
@deps density path
@@ -1058,189 +1036,3 @@ function abline!(plt::Plot, a, b; kw...)
end
abline!(args...; kw...) = abline!(current(), args...; kw...)
# =================================================
# Arc and chord diagrams
"Takes an adjacency matrix and returns source, destiny and weight lists"
function mat2list{T}(mat::AbstractArray{T,2})
nrow, ncol = size(mat) # rows are sources and columns are destinies
nosymmetric = !issym(mat) # plots only triu for symmetric matrices
nosparse = !issparse(mat) # doesn't plot zeros from a sparse matrix
L = length(mat)
source = Array(Int, L)
destiny = Array(Int, L)
weight = Array(T, L)
idx = 1
for i in 1:nrow, j in 1:ncol
value = mat[i, j]
if !isnan(value) && ( nosparse || value != zero(T) ) # TODO: deal with Nullable
if i < j
source[idx] = i
destiny[idx] = j
weight[idx] = value
idx += 1
elseif nosymmetric && (i > j)
source[idx] = i
destiny[idx] = j
weight[idx] = value
idx += 1
end
end
end
resize!(source, idx-1), resize!(destiny, idx-1), resize!(weight, idx-1)
end
# ---------------------------------------------------------------------------
# Arc Diagram
curvecolor(value, min, max, grad) = getColorZ(grad, (value-min)/(max-min))
# "Plots a clockwise arc, from source to destiny, colored by weight"
# function arc!(source, destiny, weight, min, max, grad)
# radius = (destiny - source) / 2
# arc = Plots.partialcircle(0, π, 30, radius)
# x, y = Plots.unzip(arc)
# plot!(x .+ radius .+ source, y, line = (curvecolor(weight, min, max, grad), 0.5, 2), legend=false)
# end
# """
# `arcdiagram(source, destiny, weight[, grad])`
# Plots an arc diagram, form `source` to `destiny` (clockwise), using `weight` to determine the colors.
# """
# function arcdiagram(source, destiny, weight; kargs...)
# args = KW(kargs)
# grad = pop!(args, :grad, ColorGradient([colorant"darkred", colorant"darkblue"]))
# if length(source) == length(destiny) == length(weight)
# vertices = unique(vcat(source, destiny))
# sort!(vertices)
# xmin, xmax = extrema(vertices)
# plot(xlim=(xmin - 0.5, xmax + 0.5), legend=false)
# wmin,wmax = extrema(weight)
# for (i, j, value) in zip(source,destiny,weight)
# arc!(i, j, value, wmin, wmax, grad)
# end
# scatter!(vertices, zeros(length(vertices)); legend=false, args...)
# else
# throw(ArgumentError("source, destiny and weight should have the same length"))
# end
# end
# """
# `arcdiagram(mat[, grad])`
# Plots an arc diagram from an adjacency matrix, form rows to columns (clockwise),
# using the values on the matrix as weights to determine the colors.
# Doesn't show edges with value zero if the input is sparse.
# For simmetric matrices, only the upper triangular values are used.
# """
# arcdiagram{T}(mat::AbstractArray{T,2}; kargs...) = arcdiagram(mat2list(mat)...; kargs...)
# ---------------------------------------------------------------------------
# Chord diagram
arcshape(θ1, θ2) = Shape(vcat(Plots.partialcircle(θ1, θ2, 15, 1.1),
reverse(Plots.partialcircle(θ1, θ2, 15, 0.9))))
colorlist(grad, ::Void) = :darkgray
function colorlist(grad, z)
zmin, zmax = extrema(z)
RGBA{Float64}[getColorZ(grad, (zi-zmin)/(zmax-zmin)) for zi in z]'
end
"""
`chorddiagram(source, destiny, weight[, grad, zcolor, group])`
Plots a chord diagram, form `source` to `destiny`,
using `weight` to determine the edge colors using `grad`.
`zcolor` or `group` can be used to determine the node colors.
"""
function chorddiagram(source, destiny, weight; kargs...)
args = KW(kargs)
grad = pop!(args, :grad, ColorGradient([colorant"darkred", colorant"darkblue"]))
zcolor= pop!(args, :zcolor, nothing)
group = pop!(args, :group, nothing)
if zcolor !== nothing && group !== nothing
throw(ErrorException("group and zcolor can not be used together."))
end
if length(source) == length(destiny) == length(weight)
plt = plot(xlim=(-2,2), ylim=(-2,2), legend=false, grid=false,
xticks=nothing, yticks=nothing,
xlim=(-1.2,1.2), ylim=(-1.2,1.2))
nodemin, nodemax = extrema(vcat(source, destiny))
weightmin, weightmax = extrema(weight)
A = 1.5π # Filled space
B = 0.5π # White space (empirical)
Δα = A / nodemax
Δβ = B / nodemax
δ = Δα + Δβ
for i in 1:length(source)
curve = BezierCurve(P2[ (cos((source[i ]-1)*δ + 0.5Δα), sin((source[i ]-1)*δ + 0.5Δα)), (0,0),
(cos((destiny[i]-1)*δ + 0.5Δα), sin((destiny[i]-1)*δ + 0.5Δα)) ])
plot!(curve_points(curve), line = (Plots.curvecolor(weight[i], weightmin, weightmax, grad), 1, 1))
end
if group === nothing
c = colorlist(grad, zcolor)
elseif length(group) == nodemax
idx = collect(0:(nodemax-1))
for g in group
plot!([arcshape(n*δ, n*δ + Δα) for n in idx[group .== g]]; args...)
end
return plt
else
throw(ErrorException("group should the ", nodemax, " elements."))
end
plot!([arcshape(n*δ, n*δ + Δα) for n in 0:(nodemax-1)]; mc=c, args...)
return plt
else
throw(ArgumentError("source, destiny and weight should have the same length"))
end
end
"""
`chorddiagram(mat[, grad, zcolor, group])`
Plots a chord diagram from an adjacency matrix,
using the values on the matrix as weights to determine edge colors.
Doesn't show edges with value zero if the input is sparse.
For simmetric matrices, only the upper triangular values are used.
`zcolor` or `group` can be used to determine the node colors.
"""
chorddiagram(mat::AbstractMatrix; kargs...) = chorddiagram(mat2list(mat)...; kargs...)
+2 -453
View File
@@ -7,7 +7,7 @@
typealias FuncOrFuncs @compat(Union{Function, AVec{Function}})
all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :heatmap, :surface, :wireframe, :contour3d), get(d, :seriestype, :none))
all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none))
# missing
convertToAnyVector(v::@compat(Void), d::KW) = Any[nothing], nothing
@@ -21,8 +21,7 @@ convertToAnyVector{T<:Number}(v::AVec{T}, d::KW) = Any[v], nothing
# string vector
convertToAnyVector{T<:@compat(AbstractString)}(v::AVec{T}, d::KW) = Any[v], nothing
# numeric matrix
function convertToAnyVector{T<:Number}(v::AMat{T}, d::KW)
function convertToAnyVector(v::AMat, d::KW)
if all3D(d)
Any[Surface(v)]
else
@@ -30,14 +29,6 @@ function convertToAnyVector{T<:Number}(v::AMat{T}, d::KW)
end, nothing
end
# other matrix... vector of columns
function convertToAnyVector(m::AMat, d::KW)
Any[begin
v = vec(m[:,i])
length(v) == 1 ? v[1] : v
end for i=1:size(m,2)], nothing
end
# function
convertToAnyVector(f::Function, d::KW) = Any[f], nothing
@@ -106,445 +97,3 @@ compute_xyz(x::Void, y::Void, z::FuncOrFuncs) = error("If you want to plot the f
compute_xyz(x::Void, y::Void, z::Void) = error("x/y/z are all nothing!")
# --------------------------------------------------------------------
# # create n=max(mx,my) series arguments. the shorter list is cycled through
# # note: everything should flow through this
# function build_series_args(plt::AbstractPlot, kw::KW) #, idxfilter)
# x, y, z = map(sym -> pop!(kw, sym, nothing), (:x, :y, :z))
# if nothing == x == y == z
# return [], nothing, nothing
# end
#
# xs, xmeta = convertToAnyVector(x, kw)
# ys, ymeta = convertToAnyVector(y, kw)
# zs, zmeta = convertToAnyVector(z, kw)
#
# fr = pop!(kw, :fillrange, nothing)
# fillranges, _ = if typeof(fr) <: Number
# ([fr],nothing)
# else
# convertToAnyVector(fr, kw)
# end
#
# mx = length(xs)
# my = length(ys)
# mz = length(zs)
# ret = Any[]
# for i in 1:max(mx, my, mz)
#
# # try to set labels using ymeta
# d = copy(kw)
# if !haskey(d, :label) && ymeta != nothing
# if isa(ymeta, Symbol)
# d[:label] = string(ymeta)
# elseif isa(ymeta, AVec{Symbol})
# d[:label] = string(ymeta[mod1(i,length(ymeta))])
# end
# end
#
# # build the series arg dict
# numUncounted = pop!(d, :numUncounted, 0)
# commandIndex = i + numUncounted
# n = plt.n + i
#
# dumpdict(d, "before getSeriesArgs")
# d = getSeriesArgs(plt.backend, getattr(plt, n), d, commandIndex, convertSeriesIndex(plt, n), n)
# dumpdict(d, "after getSeriesArgs")
#
# d[:x], d[:y], d[:z] = compute_xyz(xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)])
# st = d[:seriestype]
#
# # for seriestype `line`, need to sort by x values
# if st == :line
# # order by x
# indices = sortperm(d[:x])
# d[:x] = d[:x][indices]
# d[:y] = d[:y][indices]
# d[:seriestype] = :path
# end
#
# # special handling for missing x in box plot... all the same category
# if st == :box && xs[mod1(i,mx)] == nothing
# d[:x] = ones(Int, length(d[:y]))
# end
#
# # map functions to vectors
# if isa(d[:marker_z], Function)
# d[:marker_z] = map(d[:marker_z], d[:x])
# end
#
# # @show fillranges
# d[:fillrange] = fillranges[mod1(i,length(fillranges))]
# if isa(d[:fillrange], Function)
# d[:fillrange] = map(d[:fillrange], d[:x])
# end
#
# # handle error bars
# for esym in (:xerror, :yerror)
# if get(d, esym, nothing) != nothing
# # we make a copy of the KW and apply an errorbar recipe
# append!(ret, apply_series_recipe(copy(d), Val{esym}))
# end
# end
#
# # handle ribbons
# if get(d, :ribbon, nothing) != nothing
# rib = d[:ribbon]
# d[:fillrange] = (d[:y] - rib, d[:y] + rib)
# end
#
# # handle quiver plots
# # either a series of velocity vectors are passed in (`:quiver` keyword),
# # or we just add arrows to the path
#
# # if st == :quiver
# # d[:seriestype] = st = :path
# # d[:linewidth] = 0
# # end
# if get(d, :quiver, nothing) != nothing
# append!(ret, apply_series_recipe(copy(d), Val{:quiver}))
# elseif st == :quiver
# d[:seriestype] = st = :path
# d[:arrow] = arrow()
# end
#
# # now that we've processed a given series... optionally split into
# # multiple dicts through a recipe (for example, a box plot is split into component
# # parts... polygons, lines, and scatters)
# # note: we pass in a Val type (i.e. Val{:box}) so that we can dispatch on the seriestype
# kwlist = apply_series_recipe(d, Val{st})
# append!(ret, kwlist)
#
# # # add it to our series list
# # push!(ret, d)
# end
#
# ret, xmeta, ymeta
# end
#
#
# # --------------------------------------------------------------------
# # process_inputs
# # --------------------------------------------------------------------
#
# # These methods take a plot and the keyword arguments, and processes the input
# # arguments (x/y/z, group, etc), populating the KW dict with appropriate values.
#
# # --------------------------------------------------------------------
# # 0 arguments
# # --------------------------------------------------------------------
#
# # don't do anything
# function process_inputs(plt::AbstractPlot, d::KW)
# end
#
# # --------------------------------------------------------------------
# # 1 argument
# # --------------------------------------------------------------------
#
# function process_inputs(plt::AbstractPlot, d::KW, n::Integer)
# # d[:x], d[:y], d[:z] = zeros(0), zeros(0), zeros(0)
# d[:x] = d[:y] = d[:z] = n
# end
#
# # no special handling... assume x and z are nothing
# function process_inputs(plt::AbstractPlot, d::KW, y)
# d[:y] = y
# end
#
# # matrix... is it z or y?
# function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, mat::AMat{T})
# if all3D(d)
# n,m = size(mat)
# d[:x], d[:y], d[:z] = 1:n, 1:m, mat
# else
# d[:y] = mat
# end
# end
#
# # images - grays
# function process_inputs{T<:Gray}(plt::AbstractPlot, d::KW, mat::AMat{T})
# d[:seriestype] = :image
# n,m = size(mat)
# d[:x], d[:y], d[:z] = 1:n, 1:m, Surface(mat)
# # handle images... when not supported natively, do a hack to use heatmap machinery
# if !nativeImagesSupported()
# d[:seriestype] = :heatmap
# d[:yflip] = true
# d[:z] = Surface(convert(Matrix{Float64}, mat.surf))
# d[:fillcolor] = ColorGradient([:black, :white])
# end
# end
#
# # images - colors
# function process_inputs{T<:Colorant}(plt::AbstractPlot, d::KW, mat::AMat{T})
# d[:seriestype] = :image
# n,m = size(mat)
# d[:x], d[:y], d[:z] = 1:n, 1:m, Surface(mat)
# # handle images... when not supported natively, do a hack to use heatmap machinery
# if !nativeImagesSupported()
# d[:yflip] = true
# imageHack(d)
# end
# end
#
#
# # plotting arbitrary shapes/polygons
# function process_inputs(plt::AbstractPlot, d::KW, shape::Shape)
# d[:x], d[:y] = shape_coords(shape)
# d[:seriestype] = :shape
# end
# function process_inputs(plt::AbstractPlot, d::KW, shapes::AVec{Shape})
# d[:x], d[:y] = shape_coords(shapes)
# d[:seriestype] = :shape
# end
# function process_inputs(plt::AbstractPlot, d::KW, shapes::AMat{Shape})
# x, y = [], []
# for j in 1:size(shapes, 2)
# tmpx, tmpy = shape_coords(vec(shapes[:,j]))
# push!(x, tmpx)
# push!(y, tmpy)
# end
# d[:x], d[:y] = x, y
# d[:seriestype] = :shape
# end
#
#
# # function without range... use the current range of the x-axis
# function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs)
# process_inputs(plt, d, f, xmin(plt), xmax(plt))
# end
#
# # --------------------------------------------------------------------
# # 2 arguments
# # --------------------------------------------------------------------
#
# function process_inputs(plt::AbstractPlot, d::KW, x, y)
# d[:x], d[:y] = x, y
# end
#
# # if functions come first, just swap the order (not to be confused with parametric functions...
# # as there would be more than one function passed in)
# function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, x)
# @assert !(typeof(x) <: FuncOrFuncs) # otherwise we'd hit infinite recursion here
# process_inputs(plt, d, x, f)
# end
#
# # --------------------------------------------------------------------
# # 3 arguments
# # --------------------------------------------------------------------
#
# # no special handling... just pass them through
# function process_inputs(plt::AbstractPlot, d::KW, x, y, z)
# d[:x], d[:y], d[:z] = x, y, z
# end
#
# # 3d line or scatter
# function process_inputs(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zvec::AVec)
# # default to path3d if we haven't set a 3d seriestype
# st = get(d, :seriestype, :none)
# if st == :scatter
# d[:seriestype] = :scatter3d
# elseif !(st in _3dTypes)
# d[:seriestype] = :path3d
# end
# d[:x], d[:y], d[:z] = x, y, zvec
# end
#
# # surface-like... function
# 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{TX,TY,TZ}(plt::AbstractPlot, d::KW, x::AVec{TX}, y::AVec{TY}, zmat::AMat{TZ})
# # @assert size(zmat) == (length(x), length(y))
# # 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
# d[:x], d[:y], d[:z] = x, y, Surface{Matrix{TZ}}(zmat)
# if !like_surface(get(d, :seriestype, :none))
# d[:seriestype] = :contour
# end
# end
#
# # surfaces-like... general x, y grid
# function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, x::AMat{T}, y::AMat{T}, zmat::AMat{T})
# @assert size(zmat) == size(x) == size(y)
# # d[:x], d[:y], d[:z] = Any[x], Any[y], Surface{Matrix{Float64}}(zmat)
# d[:x], d[:y], d[:z] = map(Surface{Matrix{Float64}}, (x, y, zmat))
# if !like_surface(get(d, :seriestype, :none))
# d[:seriestype] = :contour
# end
# end
#
#
# # --------------------------------------------------------------------
# # Parametric functions
# # --------------------------------------------------------------------
#
# # special handling... xmin/xmax with function(s)
# function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number)
# width = get(plt.attr, :size, (100,))[1]
# x = linspace(xmin, xmax, width)
# process_inputs(plt, d, x, f)
# end
#
# # special handling... xmin/xmax with parametric function(s)
# process_inputs{T<:Number}(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, u::AVec{T}) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u))
# process_inputs{T<:Number}(plt::AbstractPlot, d::KW, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u))
# process_inputs(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, umin::Number, umax::Number, numPoints::Int = 1000) = process_inputs(plt, d, fx, fy, linspace(umin, umax, numPoints))
#
# # special handling... 3D parametric function(s)
# process_inputs{T<:Number}(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, u::AVec{T}) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u))
# process_inputs{T<:Number}(plt::AbstractPlot, d::KW, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u))
# process_inputs(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, umin::Number, umax::Number, numPoints::Int = 1000) = process_inputs(plt, d, fx, fy, fz, linspace(umin, umax, numPoints))
#
#
# # --------------------------------------------------------------------
# # Lists of tuples and FixedSizeArrays
# # --------------------------------------------------------------------
#
# # if we get an unhandled tuple, just splat it in
# function process_inputs(plt::AbstractPlot, d::KW, tup::Tuple)
# process_inputs(plt, d, tup...)
# end
#
# # (x,y) tuples
# function process_inputs{R1<:Number,R2<:Number}(plt::AbstractPlot, d::KW, xy::AVec{Tuple{R1,R2}})
# process_inputs(plt, d, unzip(xy)...)
# end
# function process_inputs{R1<:Number,R2<:Number}(plt::AbstractPlot, d::KW, xy::Tuple{R1,R2})
# process_inputs(plt, d, [xy[1]], [xy[2]])
# end
#
# # (x,y,z) tuples
# function process_inputs{R1<:Number,R2<:Number,R3<:Number}(plt::AbstractPlot, d::KW, xyz::AVec{Tuple{R1,R2,R3}})
# process_inputs(plt, d, unzip(xyz)...)
# end
# function process_inputs{R1<:Number,R2<:Number,R3<:Number}(plt::AbstractPlot, d::KW, xyz::Tuple{R1,R2,R3})
# process_inputs(plt, d, [xyz[1]], [xyz[2]], [xyz[3]])
# end
#
# # 2D FixedSizeArrays
# function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xy::AVec{FixedSizeArrays.Vec{2,T}})
# process_inputs(plt, d, unzip(xy)...)
# end
# function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xy::FixedSizeArrays.Vec{2,T})
# process_inputs(plt, d, [xy[1]], [xy[2]])
# end
#
# # 3D FixedSizeArrays
# function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xyz::AVec{FixedSizeArrays.Vec{3,T}})
# process_inputs(plt, d, unzip(xyz)...)
# end
# function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xyz::FixedSizeArrays.Vec{3,T})
# process_inputs(plt, d, [xyz[1]], [xyz[2]], [xyz[3]])
# end
#
# # --------------------------------------------------------------------
# # handle grouping
# # --------------------------------------------------------------------
#
# # function process_inputs(plt::AbstractPlot, d::KW, groupby::GroupBy, args...)
# # ret = Any[]
# # error("unfinished after series reorg")
# # for (i,glab) in enumerate(groupby.groupLabels)
# # # TODO: don't automatically overwrite labels
# # kwlist, xmeta, ymeta = process_inputs(plt, d, args...,
# # idxfilter = groupby.groupIds[i],
# # label = string(glab),
# # numUncounted = length(ret)) # we count the idx from plt.n + numUncounted + i
# # append!(ret, kwlist)
# # end
# # ret, nothing, nothing # TODO: handle passing meta through
# # end
# --------------------------------------------------------------------
# For DataFrame support. Imports DataFrames and defines the necessary methods which support them.
# --------------------------------------------------------------------
# function setup_dataframes()
# @require DataFrames begin
# # @eval begin
# # import DataFrames
#
# DFS = Union{Symbol, AbstractArray{Symbol}}
#
# function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, dfs::DFS)
# if isa(dfs, Symbol)
# get!(d, Symbol(letter * "label"), string(dfs))
# collect(df[dfs])
# else
# get!(d, :label, reshape(dfs, 1, length(dfs)))
# Any[collect(df[s]) for s in dfs]
# end
# end
#
# function handle_group(df::DataFrames.AbstractDataFrame, d::KW)
# if haskey(d, :group)
# g = d[:group]
# if isa(g, Symbol)
# d[:group] = collect(df[g])
# end
# end
# end
#
# @recipe function plot(df::DataFrames.AbstractDataFrame, sy::DFS)
# handle_group(df, d)
# handle_dfs(df, d, "y", sy)
# end
#
# @recipe function plot(df::DataFrames.AbstractDataFrame, sx::DFS, sy::DFS)
# handle_group(df, d)
# x = handle_dfs(df, d, "x", sx)
# y = handle_dfs(df, d, "y", sy)
# x, y
# end
#
# @recipe function plot(df::DataFrames.AbstractDataFrame, sx::DFS, sy::DFS, sz::DFS)
# handle_group(df, d)
# x = handle_dfs(df, d, "x", sx)
# y = handle_dfs(df, d, "y", sy)
# z = handle_dfs(df, d, "z", sz)
# x, y, z
# end
#
# # get_data(df::DataFrames.AbstractDataFrame, arg::Symbol) = df[arg]
# # get_data(df::DataFrames.AbstractDataFrame, arg) = arg
# #
# # function process_inputs(plt::AbstractPlot, d::KW, df::DataFrames.AbstractDataFrame, args...)
# # # d[:dataframe] = df
# # process_inputs(plt, d, map(arg -> get_data(df, arg), args)...)
# # end
# #
# # # expecting the column name of a dataframe that was passed in... anything else should error
# # function extractGroupArgs(s::Symbol, df::DataFrames.AbstractDataFrame, args...)
# # if haskey(df, s)
# # return extractGroupArgs(df[s])
# # else
# # error("Got a symbol, and expected that to be a key in d[:dataframe]. s=$s d=$d")
# # end
# # end
#
# # function getDataFrameFromKW(d::KW)
# # get(d, :dataframe) do
# # error("Missing dataframe argument!")
# # end
# # end
#
# # # the conversion functions for when we pass symbols or vectors of symbols to reference dataframes
# # convertToAnyVector(s::Symbol, d::KW) = Any[getDataFrameFromKW(d)[s]], s
# # convertToAnyVector(v::AVec{Symbol}, d::KW) = (df = getDataFrameFromKW(d); Any[df[s] for s in v]), v
#
# end
# end
-9
View File
@@ -180,15 +180,6 @@ end
newargs
end
# @recipe f(x, y, z) = SliceIt, apply_recipe(typeof(x), x), apply_recipe(typeof(y), y), apply_recipe(typeof(z), z)
# @recipe f(x, y) = SliceIt, apply_recipe(typeof(x), x), apply_recipe(typeof(y), y), nothing
# @recipe f(y) = SliceIt, nothing, apply_recipe(typeof(y), y), nothing
# # pass these through to the slicer
# @recipe f(x, y, z) = SliceIt, x, y, z
# @recipe f(x, y) = SliceIt, x, y, nothing
# @recipe f(y) = SliceIt, nothing, y, nothing
# # --------------------------------------------------------------------
# # 1 argument
+27
View File
@@ -137,6 +137,30 @@ function imageHack(d::KW)
end
# ---------------------------------------------------------------
type Segments
pts::Vector{Float64}
end
Segments() = Segments(zeros(0))
function Base.push!(segments::Segments, vs...)
push!(segments.pts, NaN)
for v in vs
push!(segments.pts, v)
end
segments
end
function Base.push!(segments::Segments, vs::AVec)
push!(segments.pts, NaN)
for v in vs
push!(segments.pts, v)
end
segments
end
# -----------------------------------------------------
# helper to manage NaN-separated segments
@@ -189,6 +213,9 @@ end
nop() = nothing
notimpl() = error("This has not been implemented yet")
Base.cycle(wrapper::InputWrapper, idx::Int) = wrapper.obj
Base.cycle(wrapper::InputWrapper, idx::AVec{Int}) = wrapper.obj
Base.cycle(v::AVec, idx::Int) = v[mod1(idx, length(v))]
Base.cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
Base.cycle(v, idx::Int) = v
+1 -1
View File
@@ -22,7 +22,7 @@ default(size=(500,300))
# TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that
# is referenced in a button press callback (the button clicked callback will call notify() on that condition)
const _current_plots_version = v"0.7.2"
const _current_plots_version = v"0.7.4"
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
+1 -1
View File
@@ -30,7 +30,7 @@ facts("GR") do
@fact gr() --> Plots.GRBackend()
@fact backend() --> Plots.GRBackend()
@linux_only image_comparison_facts(:gr, skip=[30], eps=img_eps)
@linux_only image_comparison_facts(:gr, skip=[], eps=img_eps)
end
facts("Plotly") do
+36
View File
@@ -0,0 +1,36 @@
import SnoopCompile
### Log the compiles
# This only needs to be run once (to generate "/tmp/plots_compiles.csv")
# SnoopCompile.@snoop "/tmp/plots_compiles.csv" begin
# include(Pkg.dir("Plots", "test","runtests.jl"))
# end
# ----------------------------------------------------------
### Parse the compiles and generate precompilation scripts
# This can be run repeatedly to tweak the scripts
# IMPORTANT: we must have the module(s) defined for the parcelation
# step, otherwise we will get no precompiles for the Plots module
using Plots
data = SnoopCompile.read("/tmp/plots_compiles.csv")
# The Plots tests are run inside a module PlotsTest, so all
# the precompiles get credited to PlotsTest. Credit them to Plots instead.
subst = Dict("PlotsTests"=>"Plots")
# Blacklist helps fix problems:
# - MIME uses type-parameters with symbols like :image/png, which is
# not parseable
blacklist = ["MIME"]
# Use these two lines if you want to create precompile functions for
# individual packages
pc, discards = SnoopCompile.parcel(data[end:-1:1,2], subst=subst, blacklist=blacklist)
SnoopCompile.write("/tmp/precompile", pc)
pdir = Pkg.dir("Plots")
run(`cp /tmp/precompile/precompile_Plots.jl $pdir/src/precompile.jl`)