Compare commits

..

50 Commits

Author SHA1 Message Date
Thomas Breloff 011f51fbd9 recipe postprocessing for aliases and magic args 2016-08-19 19:04:10 -04:00
Tom Breloff 333714911c Merge pull request #452 from TotalVerb/master
Remove unnecessary `_print` extension
2016-08-19 15:49:09 -04:00
Tom Breloff f165423527 Merge pull request #453 from maximsch2/master
add DateTime recepie
2016-08-19 15:48:56 -04:00
Maxim Grechkin 428fbb9cb9 add DateTime recepie 2016-08-19 12:43:30 -07:00
Thomas Breloff 342f9c60b2 improved twinx 2016-08-19 09:59:50 -04:00
Thomas Breloff e13070cd6d working on twinx 2016-08-19 02:22:12 -04:00
Thomas Breloff 76bb6bab96 gr support for mirror; switch Axis.sp for sps; fixes to inset sp setup and linking 2016-08-19 01:55:55 -04:00
Fengyang Wang ff7b147888 Remove unnecessary _print extension 2016-08-19 01:40:20 -04:00
Thomas Breloff 55a598b796 fix mirror default 2016-08-18 21:23:50 -04:00
Thomas Breloff f63eac9a73 added mirror and implemented in pyplot 2016-08-18 21:11:03 -04:00
Thomas Breloff 8d7c4cd108 type recipe for Dates; closes #451 2016-08-18 17:33:26 -04:00
Thomas Breloff 99f608defb bar fix: reset orientation; layout fixes 2016-08-18 17:33:26 -04:00
Thomas Breloff 34596ada49 orientation extrema fix 2016-08-18 17:33:26 -04:00
Thomas Breloff 60c8f6f578 atom fix; add_backend for pyplot/plotly/plotlyjs; closes #449 2016-08-18 17:33:26 -04:00
Tom Breloff 959da6c5ae Merge pull request #450 from anriseth/anriseth/saveeps
Add eps to savefig
2016-08-18 17:32:53 -04:00
Asbjørn Nilsen Riseth 5c127f945f Add eps to savefig 2016-08-18 15:51:51 +01:00
Thomas Breloff 74ec733444 check for empty inputs; closes #448 2016-08-16 09:47:14 -04:00
Thomas Breloff f560884436 _plotly_js_path fix 2016-08-12 11:02:14 -04:00
Thomas Breloff f68f82e3f4 gr: fix image and alpha; switch transpose_z to use permutedims 2016-08-12 10:30:53 -04:00
Tom Breloff 56bd8006bc Merge pull request #446 from tkelman/patch-1
another Pkg.dir -> dirname(@__FILE__) replacement
2016-08-12 10:23:24 -04:00
Tony Kelman ca062c3ce2 another Pkg.dir -> dirname(@__FILE__) replacement
ref #425
2016-08-12 02:46:33 -07:00
Thomas Breloff 90aba32ca5 fix for spurious scale warnings; closes #444 2016-08-11 13:11:22 -04:00
Thomas Breloff e164a8274a fix pyplot heatmap; closes #388 2016-08-10 14:32:54 -04:00
Thomas Breloff 23b25d4954 fixed rotate 2016-08-10 09:42:21 -04:00
Patrick Kofod Mogensen bc7c8993c0 Support *ticks in PGFplots. 2016-08-10 09:41:43 -04:00
Thomas Breloff 9db7de8373 added skinny markers + and x; closes #436 2016-08-09 17:09:53 -04:00
Thomas Breloff f8fddb49e2 fix for sticks default fillrange for log scale; closes #435 2016-08-09 16:38:32 -04:00
Thomas Breloff 991b2e7ca5 fix clims for line_z in pyplot; closes #395 2016-08-09 16:28:40 -04:00
Thomas Breloff 54cd96e5e0 handle axis=nothing; closes #428 2016-08-09 15:42:09 -04:00
Thomas Breloff 599f91860a allow failures: nightly 2016-08-09 15:03:29 -04:00
Thomas Breloff d59564999c Atom inline display 2016-08-09 13:15:04 -04:00
Tom Breloff 5a87adaa7f Merge pull request #425 from tkelman/nopkgdir
Use dirname(@__FILE__) instead of Pkg.dir
2016-08-05 16:57:56 -04:00
Tony Kelman 4e6150fe1e use S3 links on appveyor
and add fast-fail snippet
2016-08-02 20:39:49 -07:00
Tony Kelman 553125713d 0.4 no longer supported on master 2016-08-02 20:37:39 -07:00
Tony Kelman 5583d9f315 Use dirname(@__FILE__) instead of Pkg.dir
This allows installing the package elsewhere.

Add testing against 0.5 to Travis - this runs the most
recent RC now, release once final tags are done
2016-08-02 22:52:33 -04:00
Thomas Breloff 20df4967a4 NEWS 2016-08-02 21:24:17 -04:00
Thomas Breloff 6a30435071 gr: added GKS_DOUBLE_BUF to display and removed forgotten debugging statement 2016-08-02 21:04:36 -04:00
Thomas Breloff 5776ff1fdf clear insets after use; closes #416 2016-07-26 15:48:41 -04:00
Thomas Breloff bbb00816f1 axis formatter 2016-07-26 12:34:06 -04:00
Thomas Breloff 3b1c409fd7 reset GR viewport for annotations; fixes #398 2016-07-25 16:06:24 -04:00
Thomas Breloff ee68798de3 add back single function recipe; closes #401 2016-07-25 15:40:28 -04:00
Thomas Breloff 3ae8dc9bd7 fix cycle; fix GR fill 2016-07-25 15:25:50 -04:00
Thomas Breloff e9dca92c11 remove mkdir call in tests; closes #397 2016-07-22 11:18:28 -04:00
Thomas Breloff 98cce223e9 unicodeplots size fix 2016-07-22 09:43:43 -04:00
Thomas Breloff 1d7a470f78 plotly ticks fix 2016-07-21 10:52:06 -04:00
Thomas Breloff 461d5efc4b removed release from travis; push for series; update for subplot 2016-07-20 20:44:28 -04:00
Thomas Breloff 705dbf60fa removed compat; added series update methods 2016-07-20 15:15:40 -04:00
Thomas Breloff bb180ad59a UTF8String to String 2016-07-20 09:40:10 -04:00
Thomas Breloff 463e1bcb90 require julia 0.5-; writemime to show 2016-07-19 16:51:05 -04:00
Thomas Breloff 22ac2df595 bump version; NEWS 2016-07-19 12:13:40 -04:00
39 changed files with 656 additions and 330 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ os:
- linux
- osx
julia:
- release
- 0.5
- nightly
matrix:
allow_failures:
+37 -2
View File
@@ -3,11 +3,46 @@
#### notes on release changes, ongoing development, and future planned work
- All new development should target 0.7!
- All new development should target 0.9!
- Minor version 0.8 is the last one to support Julia 0.4!!
- Critical bugfixes only
---
## 0.8 (current master/dev)
## 0.9 (current master/dev)
#### 0.9.0
- fixes to cycle
- add back single function recipe: `plot!(cos)`
- new axis formatter attribute... accepts functions to convert numbers to strings
- fix for inset plots
- GR:
- fillrange fix
- annotations fix
- force double buffering in display
---
## 0.8
#### 0.8.2 (backported bug fixes for julia 0.4)
- plotly ticks fix
- unicodeplots size fix
- remove mkdir call in tests
#### 0.8.1
- manual drawing of axes/ticks/labels
- get_ticks uses optimize_ticks and Showoff
- changed PLOTS_DEFAULTS to be a global variable, not ENV key
- parameterized Segments for pushing tuples
- fix to axis extrema for Bool/nothing
- GR:
- manually draw 2D axes... fixes several issues and missing features
- fontsize fix
- PGFPlots: pass axis syle
#### 0.8.0
+1 -1
View File
@@ -1,4 +1,4 @@
julia 0.4
julia 0.5-
RecipesBase
PlotUtils
+11 -8
View File
@@ -1,11 +1,9 @@
environment:
matrix:
# Releases
- JULIAVERSION: "stable/win32"
- JULIAVERSION: "stable/win64"
# Nightlies
- JULIAVERSION: "download/win32"
- JULIAVERSION: "download/win64"
- JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe"
notifications:
- provider: Email
@@ -14,8 +12,13 @@ notifications:
on_build_status_changed: false
install:
# If there's a newer build queued for the same PR, cancel this one
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile($("http://status.julialang.org/"+$env:JULIAVERSION), "C:\projects\julia-binary.exe")
- ps: (new-object net.webclient).DownloadFile($("http://s3.amazonaws.com/"+$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
@@ -26,4 +29,4 @@ build_script:
test_script:
# - C:\projects\julia\bin\julia -e "Pkg.test(\"Plots\")"
- C:\projects\julia\bin\julia -e "include(Pkg.dir(\"Plots\", \"test\", \"travis_commands.jl\"))"
- C:\projects\julia\bin\julia -e "include(Pkg.dir(\"Plots\", \"test\", \"travis_commands.jl\"))"
+4 -1
View File
@@ -3,7 +3,7 @@ __precompile__()
module Plots
using Compat
# using Compat
using Reexport
# @reexport using Colors
# using Requires
@@ -34,10 +34,12 @@ export
plot,
plot!,
update!,
current,
default,
with,
twinx,
@userplot,
@shorthands,
@@ -68,6 +70,7 @@ export
backend,
backends,
backend_name,
add_backend,
aliases,
dataframes,
+6 -6
View File
@@ -1,12 +1,12 @@
immutable Animation
dir::Compat.ASCIIString
frames::Vector{Compat.ASCIIString}
dir::String
frames::Vector{String}
end
function Animation()
tmpdir = convert(Compat.ASCIIString, mktempdir())
Animation(tmpdir, Compat.ASCIIString[])
tmpdir = convert(String, mktempdir())
Animation(tmpdir, String[])
end
function frame{P<:AbstractPlot}(anim::Animation, plt::P=current())
@@ -21,7 +21,7 @@ end
"Wraps the location of an animated gif so that it can be displayed"
immutable AnimatedGif
filename::Compat.ASCIIString
filename::String
end
function gif(anim::Animation, fn = (isijulia() ? "tmp.gif" : tempname()*".gif"); fps::Integer = 20)
@@ -55,7 +55,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)
function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
write(io, "<img src=\"$(relpath(agif.filename))?$(rand())>\" />")
end
+2
View File
@@ -100,11 +100,13 @@ const _arg_desc = KW(
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
:rotation => "Number. Degrees rotation of tick labels.",
:flip => "Bool. Should we flip (reverse) the axis?",
:formatter => "Function, :scientific, or :auto. A method which converts a number to a string for tick labeling.",
:tickfont => "Font. Font of axis tick labels.",
:guidefont => "Font. Font of axis guide (label).",
:foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.",
:foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).",
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
:mirror => "Bool. Switch the side of the tick labels (right or top).",
)
+54 -30
View File
@@ -39,7 +39,7 @@ const _allTypes = vcat([
:contour, :pie, :shape, :image
], _3dTypes)
@compat const _typeAliases = Dict{Symbol,Symbol}(
const _typeAliases = Dict{Symbol,Symbol}(
:n => :none,
:no => :none,
:l => :line,
@@ -92,7 +92,7 @@ ispolar(series::Series) = ispolar(series.d[:subplot])
# ------------------------------------------------------------
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
@compat const _styleAliases = Dict{Symbol,Symbol}(
const _styleAliases = Dict{Symbol,Symbol}(
:a => :auto,
:s => :solid,
:d => :dash,
@@ -101,7 +101,7 @@ const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
)
const _allMarkers = vcat(:none, :auto, _shape_keys) #sort(collect(keys(_shapes))))
@compat const _markerAliases = Dict{Symbol,Symbol}(
const _markerAliases = Dict{Symbol,Symbol}(
:n => :none,
:no => :none,
:a => :auto,
@@ -123,9 +123,9 @@ const _allMarkers = vcat(:none, :auto, _shape_keys) #sort(collect(keys(_shapes))
:dtri => :dtriangle,
:downtri => :dtriangle,
:downtriangle => :dtriangle,
:+ => :cross,
# :+ => :cross,
:plus => :cross,
:x => :xcross,
# :x => :xcross,
:X => :xcross,
:star => :star5,
:s => :star5,
@@ -143,7 +143,7 @@ const _allMarkers = vcat(:none, :auto, _shape_keys) #sort(collect(keys(_shapes))
)
const _allScales = [:identity, :ln, :log2, :log10, :asinh, :sqrt]
@compat const _scaleAliases = Dict{Symbol,Symbol}(
const _scaleAliases = Dict{Symbol,Symbol}(
:none => :identity,
:log => :log10,
)
@@ -265,6 +265,8 @@ const _axis_defaults = KW(
:foreground_color_text => :match, # tick text color,
:foreground_color_guide => :match, # guide text color,
:discrete_values => [],
:formatter => :auto,
:mirror => false,
)
const _suppress_warnings = Set{Symbol}([
@@ -284,22 +286,24 @@ const _suppress_warnings = Set{Symbol}([
# add defaults for the letter versions
const _axis_defaults_byletter = KW()
for letter in (:x,:y,:z)
for k in (
:guide,
:lims,
:ticks,
:scale,
:rotation,
:flip,
:link,
:tickfont,
:guidefont,
:foreground_color_axis,
:foreground_color_border,
:foreground_color_text,
:foreground_color_guide,
:discrete_values
)
for k in keys(_axis_defaults)
# for k in (
# :guide,
# :lims,
# :ticks,
# :scale,
# :rotation,
# :flip,
# :link,
# :tickfont,
# :guidefont,
# :foreground_color_axis,
# :foreground_color_border,
# :foreground_color_text,
# :foreground_color_guide,
# :discrete_values,
# :formatter,
# )
_axis_defaults_byletter[Symbol(letter,k)] = :match
# allow the underscore version too: xguide or x_guide
@@ -624,6 +628,21 @@ end
function preprocessArgs!(d::KW)
replaceAliases!(d, _keyAliases)
# clear all axis stuff
if haskey(d, :axis) && d[:axis] in (:none, nothing, false)
d[:ticks] = nothing
d[:foreground_color_border] = RGBA(0,0,0,0)
d[:grid] = false
delete!(d, :axis)
end
# for letter in (:x, :y, :z)
# asym = Symbol(letter, :axis)
# if haskey(d, asym) || d[asym] in (:none, nothing, false)
# d[Symbol(letter, :ticks)] = nothing
# d[Symbol(letter, :foreground_color_border)] = RGBA(0,0,0,0)
# end
# end
# handle axis args
for letter in (:x, :y, :z)
asym = Symbol(letter, :axis)
@@ -669,7 +688,7 @@ function preprocessArgs!(d::KW)
a = d[:arrow]
d[:arrow] = if a == true
arrow()
elseif a == false
elseif a in (false, nothing, :none)
nothing
elseif !(typeof(a) <: Arrow)
arrow(wraptuple(a)...)
@@ -679,9 +698,9 @@ function preprocessArgs!(d::KW)
end
if get(d, :arrow, false) == true
d[:arrow] = arrow()
end
# if get(d, :arrow, false) == true
# d[:arrow] = arrow()
# end
# legends
if haskey(d, :legend)
@@ -778,12 +797,17 @@ function warnOnUnsupported(pkg::AbstractBackend, d::KW)
end
function warnOnUnsupported_scales(pkg::AbstractBackend, d::KW)
scales = supported_scales(pkg)
for k in (:xscale, :yscale, :zscale, :scale)
if haskey(d, k)
v = d[k]
v = get(_scaleAliases, v, v)
if !(v in supported_scales(pkg))
warn("scale $(d[k]) is unsupported with $pkg. Choose from: $(supported_scales(pkg))")
all_supported = if typeof(v) <: AbstractArray
all(vi -> get(_scaleAliases, vi, vi) in scales, v)
else
get(_scaleAliases, v, v) in scales
end
if !all_supported
warn("scale $v is unsupported with $pkg. Choose from: $(supported_scales(pkg))")
end
end
end
@@ -922,7 +946,7 @@ function Base.getindex(axis::Axis, k::Symbol)
v = axis.d[k]
if v == :match
if haskey(_match_map2, k)
axis.sp[_match_map2[k]]
axis.sps[1][_match_map2[k]]
else
axis[_match_map[k]]
end
+47 -27
View File
@@ -29,7 +29,7 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...)
d[:discrete_values] = []
# update the defaults
update!(Axis(sp, d), args...; kw...)
update!(Axis([sp], d), args...; kw...)
end
function get_axis(sp::Subplot, letter::Symbol)
@@ -73,6 +73,9 @@ function process_axis_arg!(d::KW, arg, letter = "")
elseif typeof(arg) <: Number
d[Symbol(letter,:rotation)] = arg
elseif typeof(arg) <: Function
d[Symbol(letter,:formatter)] = arg
else
warn("Skipped $(letter)axis arg $arg")
@@ -129,6 +132,12 @@ const _inv_scale_funcs = Dict{Symbol,Function}(
:ln => exp,
)
# const _label_func = Dict{Symbol,Function}(
# :log10 => x -> "10^$x",
# :log2 => x -> "2^$x",
# :ln => x -> "e^$x",
# )
const _label_func = Dict{Symbol,Function}(
:log10 => x -> "10^$x",
:log2 => x -> "2^$x",
@@ -141,41 +150,44 @@ invscalefunc(scale::Symbol) = x -> get(_inv_scale_funcs, scale, identity)(Float6
labelfunc(scale::Symbol, backend::AbstractBackend) = get(_label_func, scale, string)
function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
lims = axis_limits(axis)
amin,amax = axis_limits(axis)
# scale the limits
scale = axis[:scale]
scaled_lims = map(scalefunc(scale), lims)
# @show lims scaled_lims
sf = scalefunc(scale)
# get a list of well-laid-out ticks
cv = if ticks == nothing
optimize_ticks(scaled_lims...,
scaled_ticks = if ticks == nothing
optimize_ticks(
sf(amin),
sf(amax);
k_min = 5, # minimum number of ticks
k_max = 8, # maximum number of ticks
# span_buffer = 0.0 # padding buffer in case nice ticks are closeby
)[1]
else
ticks
map(sf, ticks)
end
unscaled_ticks = map(invscalefunc(scale), scaled_ticks)
# # expand to ensure we see all the ticks
# expand_extrema!(axis, cv)
# rescale and return values and labels
# @show cv
ticklabels = if any(isfinite, cv)
map(labelfunc(scale, backend()), Showoff.showoff(cv, :plain))
labels = if any(isfinite, unscaled_ticks)
formatter = axis[:formatter]
if formatter == :auto
# the default behavior is to make strings of the scaled values and then apply the labelfunc
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain))
elseif formatter == :scientific
Showoff.showoff(unscaled_ticks, :scientific)
else
# there was an override for the formatter... use that on the unscaled ticks
map(formatter, unscaled_ticks)
end
else
UTF8String[]
# no finite ticks to show...
String[]
end
tickvals = map(invscalefunc(scale), cv)
# @show tickvals ticklabels
# ticklabels = Showoff.showoff(tickvals, scale == :log10 ? :scientific : :auto)
tickvals, ticklabels
# basestr = scale == :log10 ? "10^" : scale == :log2 ? "2^" : scale == :ln ? "e^" : ""
# tickvals, ["$basestr$cvi" for cvi in cv]
# @show unscaled_ticks labels
# labels = Showoff.showoff(unscaled_ticks, scale == :log10 ? :scientific : :auto)
unscaled_ticks, labels
end
# return (continuous_values, discrete_values) for the ticks on this axis
@@ -243,9 +255,16 @@ end
function expand_extrema!(sp::Subplot, d::KW)
vert = isvertical(d)
# first expand for the data
for letter in (:x, :y, :z)
data = d[letter]
data = d[if vert
letter
else
letter == :x ? :y : letter == :y ? :x : :z
end]
# data = d[letter]
axis = sp.attr[Symbol(letter, "axis")]
if eltype(data) <: Number || (isa(data, Surface) && all(di -> isa(di, Number), data.surf))
if !(eltype(data) <: Number)
@@ -269,7 +288,6 @@ function expand_extrema!(sp::Subplot, d::KW)
# end
# expand for fillrange
vert = isvertical(d)
fr = d[:fillrange]
if fr == nothing && d[:seriestype] == :bar
fr = 0.0
@@ -323,9 +341,11 @@ end
function default_should_widen(axis::Axis)
should_widen = false
if axis[:scale] == :identity
for series in series_list(axis.sp)
if series.d[:seriestype] in (:scatter,) || series.d[:markershape] != :none
should_widen = true
for sp in axis.sps
for series in series_list(sp)
if series.d[:seriestype] in (:scatter,) || series.d[:markershape] != :none
should_widen = true
end
end
end
end
+12
View File
@@ -44,6 +44,9 @@ include("backends/web.jl")
# ---------------------------------------------------------
add_backend(pkg::Symbol) = add_backend(_backend_instance(pkg))
add_backend(b::AbstractBackend) = warn("No custom install defined for $(backend_name(b))")
# don't do anything as a default
_create_backend_figure(plt::Plot) = nothing
_prepare_plot_object(plt::Plot) = nothing
@@ -77,6 +80,15 @@ function _update_min_padding!(sp::Subplot)
toppad = sp[:top_margin] + title_padding(sp)
rightpad = sp[:right_margin]
bottompad = tick_padding(sp[:xaxis]) + sp[:bottom_margin] + guide_padding(sp[:xaxis])
# switch them?
if sp[:xaxis][:mirror]
bottompad, toppad = toppad, bottompad
end
if sp[:yaxis][:mirror]
leftpad, rightpad = rightpad, leftpad
end
# @show (leftpad, toppad, rightpad, bottompad)
sp.minpad = (leftpad, toppad, rightpad, bottompad)
end
+1 -1
View File
@@ -194,7 +194,7 @@ end
# ----------------------------------------------------------------
function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{BokehBackend})
function Base.show(io::IO, ::MIME"image/png", plt::AbstractPlot{BokehBackend})
# TODO: write a png to io
warn("mime png not implemented")
end
+8 -8
View File
@@ -41,7 +41,7 @@ function _initialize_backend(::GadflyBackend; kw...)
@eval begin
import Gadfly, Compose
export Gadfly, Compose
include(joinpath(Pkg.dir("Plots"), "src", "backends", "gadfly_shapes.jl"))
include(joinpath(dirname(@__FILE__), "gadfly_shapes.jl"))
end
end
@@ -244,7 +244,7 @@ function addToGadflyLegend(plt::Plot, d::KW)
# add the legend if needed
if all(g -> !isa(g, Gadfly.Guide.ManualColorKey), gplt.guides)
unshift!(gplt.guides, Gadfly.Guide.manual_color_key("", @compat(AbstractString)[], Color[]))
unshift!(gplt.guides, Gadfly.Guide.manual_color_key("", AbstractString[], Color[]))
end
# now add the series to the legend
@@ -456,7 +456,7 @@ function updateGadflyAxisFlips(gplt, d::KW, xlims, ylims, xfunc, yfunc)
end
function findGuideAndSet(gplt, t::DataType, args...; kw...) #s::@compat(AbstractString))
function findGuideAndSet(gplt, t::DataType, args...; kw...)
for (i,guide) in enumerate(gplt.guides)
if isa(guide, t)
gplt.guides[i] = t(args...; kw...)
@@ -537,7 +537,7 @@ end
# ----------------------------------------------------------------
function createGadflyAnnotationObject(x, y, val::@compat(AbstractString))
function createGadflyAnnotationObject(x, y, val::AbstractString)
Gadfly.Guide.annotation(Compose.compose(
Compose.context(),
Compose.text(x, y, val)
@@ -558,7 +558,7 @@ function createGadflyAnnotationObject(x, y, txt::PlotText)
))
end
function _add_annotations{X,Y,V}(plt::Plot{GadflyBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
function _add_annotations{X,Y,V}(plt::Plot{GadflyBackend}, anns::AVec{Tuple{X,Y,V}})
for ann in anns
push!(plt.o.guides, createGadflyAnnotationObject(ann...))
end
@@ -677,7 +677,7 @@ setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.attr[:size]...)
# -------------------------------------------------------------------------
function dowritemime{P<:Union{GadflyBackend,ImmerseBackend}}(io::IO, func, plt::AbstractPlot{P})
function doshow{P<:Union{GadflyBackend,ImmerseBackend}}(io::IO, func, plt::AbstractPlot{P})
gplt = getGadflyContext(plt)
setGadflyDisplaySize(plt)
Gadfly.draw(func(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
@@ -692,9 +692,9 @@ getGadflyWriteFunc(::MIME"application/x-tex") = Gadfly.PGF
getGadflyWriteFunc(m::MIME) = error("Unsupported in Gadfly/Immerse: ", m)
for mime in (MIME"image/png", MIME"image/svg+xml", MIME"application/pdf", MIME"application/postscript", MIME"application/x-tex")
@eval function Base.writemime{P<:Union{GadflyBackend,ImmerseBackend}}(io::IO, ::$mime, plt::AbstractPlot{P})
@eval function Base.show{P<:Union{GadflyBackend,ImmerseBackend}}(io::IO, ::$mime, plt::AbstractPlot{P})
func = getGadflyWriteFunc($mime())
dowritemime(io, func, plt)
doshow(io, func, plt)
end
end
+3 -1
View File
@@ -80,6 +80,8 @@ const _gl_marker_map = KW(
:hexagon => '⬢',
:cross => '✚',
:xcross => '❌',
:+ => '✚',
:x => '❌',
:utriangle => '▲',
:dtriangle => '▼',
:pentagon => '⬟',
@@ -311,7 +313,7 @@ function _update_plot_object(plt::Plot{GLVisualizeBackend})
gl_display(plt)
end
# function _writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{GLVisualizeBackend})
# function _show(io::IO, ::MIME"image/png", plt::AbstractPlot{GLVisualizeBackend})
# # TODO: write a png to io
# end
+53 -39
View File
@@ -74,6 +74,8 @@ const gr_markertype = KW(
:octagon => -24,
:cross => 2,
:xcross => 5,
:+ => 2,
:x => 5,
:star4 => -25,
:star5 => -26,
:star6 => -27,
@@ -197,14 +199,14 @@ function gr_polaraxes(rmin, rmax)
GR.drawarc(-r, r, -r, r, 0, 359)
end
end
for alpha in 0:45:315
a = alpha + 90
for α in 0:45:315
a = α + 90
sinf = sin(a * pi / 180)
cosf = cos(a * pi / 180)
GR.polyline([sinf, 0], [cosf, 0])
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
x, y = GR.wctondc(1.1 * sinf, 1.1 * cosf)
GR.textext(x, y, string(alpha, "^o"))
GR.textext(x, y, string(α, "^o"))
end
GR.restorestate()
end
@@ -585,22 +587,26 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
if !(xticks in (nothing, false))
# x labels
flip = sp[:yaxis][:flip]
gr_set_font(sp[:xaxis][:tickfont], valign = :top, color = sp[:xaxis][:foreground_color_axis])
mirror = sp[:xaxis][:mirror]
gr_set_font(sp[:xaxis][:tickfont], valign = (mirror ? :bottom : :top), color = sp[:xaxis][:foreground_color_axis])
for (cv, dv) in zip(xticks...)
xi, yi = GR.wctondc(cv, flip ? ymax : ymin)
# @show cv dv ymin xi yi
gr_text(xi, yi-0.01, string(dv))
# use xor ($) to get the right y coords
xi, yi = GR.wctondc(cv, (flip $ mirror) ? ymax : ymin)
# @show cv dv ymin xi yi flip mirror (flip $ mirror)
gr_text(xi, yi + (mirror ? 1 : -1) * 0.01, string(dv))
end
end
if !(yticks in (nothing, false))
# y labels
flip = sp[:xaxis][:flip]
gr_set_font(sp[:yaxis][:tickfont], halign = :right, color = sp[:yaxis][:foreground_color_axis])
mirror = sp[:yaxis][:mirror]
gr_set_font(sp[:yaxis][:tickfont], halign = (mirror ? :left : :right), color = sp[:yaxis][:foreground_color_axis])
for (cv, dv) in zip(yticks...)
xi, yi = GR.wctondc(flip ? xmax : xmin, cv)
# use xor ($) to get the right y coords
xi, yi = GR.wctondc((flip $ mirror) ? xmax : xmin, cv)
# @show cv dv xmin xi yi
gr_text(xi-0.01, yi, string(dv))
gr_text(xi + (mirror ? 1 : -1) * 0.01, yi, string(dv))
end
end
@@ -646,7 +652,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# TODO: can we remove?
gr_set_font(xaxis[:tickfont])
GR.setcolormap(1000 + GR.COLORMAP_COOLWARM)
# GR.setcolormap(1000 + GR.COLORMAP_COOLWARM)
for (idx, series) in enumerate(series_list(sp))
st = series[:seriestype]
@@ -660,6 +666,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.savestate()
# update the bounding window
if ispolar(sp)
gr_set_viewport_polar()
@@ -675,14 +682,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# recompute data
if typeof(z) <: Surface
if st == :heatmap #&& size(z.surf) == (length(y), length(x))
if st == :heatmap
expand_extrema!(sp[:xaxis], (x[1]-0.5*(x[2]-x[1]), x[end]+0.5*(x[end]-x[end-1])))
expand_extrema!(sp[:yaxis], (y[1]-0.5*(y[2]-y[1]), y[end]+0.5*(y[end]-y[end-1])))
# # coords are centers... turn into edges
# xd = diff(x)
# x = vcat(x[1]-0.5xd[1], x[1]+xd, x[end]+0.5xd[end])
# yd = diff(y)
# y = vcat(y[1]-0.5yd[1], y[1]+yd, y[end]+0.5yd[end])
end
z = vec(transpose_z(series, z.surf, false))
elseif ispolar(sp)
@@ -694,21 +696,19 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
if st in (:path, :scatter)
if length(x) > 1
# do area fill
if frng != nothing
gr_set_fillcolor(series[:fillcolor]) #, series[:fillalpha])
GR.setfillintstyle(GR.INTSTYLE_SOLID)
frng = isa(frng, Number) ? Float64[frng] : frng
nx, ny, nf = length(x), length(y), length(frng)
n = max(nx, ny)
fx, fy = zeros(2n), zeros(2n)
for i=1:n
fx[i] = fx[end-i+1] = cycle(x,i)
fy[i] = cycle(y,i)
fy[end-i+1] = cycle(frng,i)
fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng))
for (i,rng) in enumerate(iter_segments(series[:x], series[:y]))
if length(rng) > 1
gr_set_fillcolor(cycle(series[:fillcolor], i))
fx = cycle(x, vcat(rng, reverse(rng)))
fy = vcat(cycle(fr_from,rng), cycle(fr_to,reverse(rng)))
# @show i rng fx fy
GR.fillarea(fx, fy)
end
end
GR.fillarea(fx, fy)
end
# draw the line(s)
@@ -809,15 +809,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
a2 = round(Int, a1 + (slices[i] / total) * 360.0)
GR.setfillcolorind(980 + (i-1) % 20)
GR.fillarc(xmin, xmax, ymin, ymax, a1, a2)
alpha = 0.5 * (a1 + a2)
cosf = r * cos(alpha * pi / 180)
sinf = r * sin(alpha * pi / 180)
α = 0.5 * (a1 + a2)
cosf = r * cos(α * pi / 180)
sinf = r * sin(α * pi / 180)
x[1] = xcenter + cosf
y[1] = ycenter + sinf
x[2] = x[1] + 0.1 * cosf
y[2] = y[1] + 0.1 * sinf
y[3] = y[2]
if 90 <= alpha < 270
if 90 <= α < 270
x[3] = x[2] - 0.05
GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF)
gr_text(x[3] - 0.01, y[3], string(labels[i]))
@@ -853,15 +853,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
elseif st == :image
img = series[:z].surf
w, h = size(img)
if eltype(img) <: Colors.AbstractGray
grey = round(UInt8, float(img) * 255)
h, w = size(img)
if eltype(z) <: Colors.AbstractGray
grey = round(UInt8, float(z) * 255)
rgba = map(c -> UInt32( 0xff000000 + Int(c)<<16 + Int(c)<<8 + Int(c) ), grey)
else
rgba = map(c -> UInt32( round(Int, alpha(c) * 255) << 24 +
round(Int, blue(c) * 255) << 16 +
round(Int, green(c) * 255) << 8 +
round(Int, red(c) * 255) ), img)
round(Int, red(c) * 255) ), z)
end
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
end
@@ -940,9 +940,22 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# add annotations
GR.savestate()
# update the bounding window
if ispolar(sp)
gr_set_viewport_polar()
else
xmin, xmax, ymin, ymax = data_lims
if xmax > xmin && ymax > ymin
GR.setwindow(xmin, xmax, ymin, ymax)
end
end
for ann in sp[:annotations]
x, y, val = ann
x, y = GR.wctondc(x, y)
x, y = if is3d(sp)
# GR.wc3towc(x, y, z)
else
GR.wctondc(x, y)
end
gr_set_font(val.font)
gr_text(x, y, val.str)
end
@@ -961,7 +974,7 @@ const _gr_mimeformats = Dict(
for (mime, fmt) in _gr_mimeformats
@eval function _writemime(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GRBackend})
@eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GRBackend})
GR.emergencyclosegks()
wstype = haskey(ENV, "GKS_WSTYPE") ? ENV["GKS_WSTYPE"] : "0"
filepath = tempname() * "." * $fmt
@@ -969,7 +982,7 @@ for (mime, fmt) in _gr_mimeformats
ENV["GKS_FILEPATH"] = filepath
gr_display(plt)
GR.emergencyclosegks()
write(io, readall(filepath))
write(io, readstring(filepath))
ENV["GKS_WSTYPE"] = wstype
rm(filepath)
end
@@ -987,6 +1000,7 @@ function _display(plt::Plot{GRBackend})
println(content)
rm(filepath)
else
ENV["GKS_DOUBLE_BUF"] = "true"
gr_display(plt)
end
end
+2 -2
View File
@@ -14,7 +14,7 @@ function _initialize_backend(::ImmerseBackend; kw...)
@eval begin
import Immerse, Gadfly, Compose, Gtk
export Immerse, Gadfly, Compose, Gtk
include(joinpath(Pkg.dir("Plots"), "src", "backends", "gadfly_shapes.jl"))
include(joinpath(dirname(@__FILE__), "gadfly_shapes.jl"))
end
end
@@ -61,7 +61,7 @@ end
# ----------------------------------------------------------------
function _add_annotations{X,Y,V}(plt::Plot{ImmerseBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
function _add_annotations{X,Y,V}(plt::Plot{ImmerseBackend}, anns::AVec{Tuple{X,Y,V}})
for ann in anns
push!(getGadflyContext(plt).guides, createGadflyAnnotationObject(ann...))
end
+11 -3
View File
@@ -64,6 +64,8 @@ const _pgfplots_markers = KW(
:none => "none",
:cross => "+",
:xcross => "x",
:+ => "+",
:x => "x",
:utriangle => "triangle*",
:dtriangle => "triangle*",
:circle => "*",
@@ -225,6 +227,11 @@ function pgf_axis(sp::Subplot, letter)
kw[Symbol(letter,:max)] = lims[2]
end
if !(axis[:ticks] in (nothing, false, :none, :auto))
push!(style, "$(letter)"*"tick = {$(join(get_ticks(axis),","))}")
end
# return the style list and KW args
style, kw
end
@@ -243,6 +250,7 @@ function _make_pgf_plot!(plt::Plot)
for letter in (:x, :y, :z)
if letter != :z || is3d(sp)
axisstyle, axiskw = pgf_axis(sp, letter)
append!(style, axisstyle)
merge!(kw, axiskw)
for sty in axisstyle
push!(style, sty)
@@ -288,12 +296,12 @@ function _make_pgf_plot!(plt::Plot)
end
function _writemime(io::IO, mime::MIME"image/svg+xml", plt::Plot{PGFPlotsBackend})
function _show(io::IO, mime::MIME"image/svg+xml", plt::Plot{PGFPlotsBackend})
_make_pgf_plot!(plt)
writemime(io, mime, plt.o)
show(io, mime, plt.o)
end
function _writemime(io::IO, mime::MIME"application/pdf", plt::Plot{PGFPlotsBackend})
function _show(io::IO, mime::MIME"application/pdf", plt::Plot{PGFPlotsBackend})
_make_pgf_plot!(plt)
# prepare the object
+13 -7
View File
@@ -47,13 +47,18 @@ is_string_supported(::PlotlyBackend) = true
# --------------------------------------------------------------------------------------
function add_backend(::PlotlyBackend)
Pkg.build("Plots")
end
const _plotly_js_path = joinpath(dirname(@__FILE__), "..", "..", "deps", "plotly-latest.min.js")
function _initialize_backend(::PlotlyBackend; kw...)
@eval begin
import JSON
JSON._print(io::IO, state::JSON.State, dt::Union{Date,DateTime}) = print(io, '"', dt, '"')
_js_path = Pkg.dir("Plots", "deps", "plotly-latest.min.js")
_js_code = open(@compat(readstring), _js_path, "r")
_js_code = open(readstring, _plotly_js_path, "r")
# borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2
_js_script = """
@@ -307,6 +312,7 @@ plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α)
const _plotly_markers = KW(
:rect => "square",
:xcross => "x",
:x => "x",
:utriangle => "triangle-up",
:dtriangle => "triangle-down",
:star5 => "star-triangle-up",
@@ -537,7 +543,7 @@ end
# ----------------------------------------------------------------
function html_head(plt::Plot{PlotlyBackend})
"<script src=\"$(Pkg.dir("Plots","deps","plotly-latest.min.js"))\"></script>"
"<script src=\"$(joinpath(dirname(@__FILE__),"..","..","deps","plotly-latest.min.js"))\"></script>"
end
function html_body(plt::Plot{PlotlyBackend}, style = nothing)
@@ -567,11 +573,11 @@ end
# ----------------------------------------------------------------
function _writemime(io::IO, ::MIME"image/png", plt::Plot{PlotlyBackend})
writemime_png_from_html(io, plt)
function _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyBackend})
show_png_from_html(io, plt)
end
function _writemime(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend})
function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend})
write(io, html_head(plt) * html_body(plt))
end
+14 -3
View File
@@ -11,6 +11,17 @@ is_string_supported(::PlotlyJSBackend) = true
# --------------------------------------------------------------------------------------
function add_backend(::PlotlyJSBackend)
if !is_installed("PlotlyJS")
Pkg.add("PlotlyJS")
@eval import Blink
Blink.AtomShell.install()
Pkg.add("Rsvg")
end
end
function _initialize_backend(::PlotlyJSBackend; kw...)
@eval begin
import PlotlyJS
@@ -63,11 +74,11 @@ end
# ----------------------------------------------------------------
function _writemime(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend})
writemime(io, MIME("text/html"), plt.o)
function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend})
show(io, MIME("text/html"), plt.o)
end
function _writemime(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend})
function _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend})
tmpfn = tempname() * ".png"
PlotlyJS.savefig(plt.o, tmpfn)
write(io, read(open(tmpfn)))
+41 -27
View File
@@ -47,6 +47,14 @@ is_subplot_supported(::PyPlotBackend) = true
# --------------------------------------------------------------------------------------
function add_backend(::PyPlotBackend)
if !is_installed("PyPlot")
withenv("PYTHON" => "") do
Pkg.add("PyPlot")
Pkg.build("PyPlot")
end
end
end
function _initialize_backend(::PyPlotBackend)
@eval begin
@@ -174,8 +182,8 @@ function py_marker(marker::Symbol)
marker == :diamond && return "D"
marker == :utriangle && return "^"
marker == :dtriangle && return "v"
# marker == :cross && return "+"
# marker == :xcross && return "x"
marker == :+ && return "+"
marker == :x && return "x"
marker == :star5 && return "*"
marker == :pentagon && return "p"
marker == :hexagon && return "h"
@@ -458,6 +466,13 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:linewidth => py_dpi_scale(plt, series[:linewidth]),
:linestyle => py_linestyle(st, series[:linestyle])
)
clims = sp[:clims]
if is_2tuple(clims)
extrakw = KW()
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
kw[:norm] = pycolors.Normalize(; extrakw...)
end
lz = collect(series[:line_z])
handle = if is3d(st)
for rng in iter_segments(x, y, z)
@@ -706,9 +721,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
if st == :heatmap
x, y, z = heatmap_edges(x), heatmap_edges(y), transpose_z(series, z.surf)
# if !(eltype(z) <: Number)
# z, discrete_colorbar_values = indices_and_unique_values(z)
# end
expand_extrema!(sp[:xaxis], x)
expand_extrema!(sp[:yaxis], y)
dvals = sp[:zaxis][:discrete_values]
if !isempty(dvals)
discrete_colorbar_values = dvals
@@ -724,21 +739,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = series[:label],
zorder = series[:series_plotindex],
cmap = py_fillcolormap(series),
edgecolors = (series[:linewidth] > 0 ? py_linecolor(series) : "face"),
# edgecolors = (series[:linewidth] > 0 ? py_linecolor(series) : "face"),
extrakw...
)
push!(handles, handle)
needs_colorbar = true
# TODO: this should probably be handled generically
# expand extrema... handle is a QuadMesh object
for path in handle[:properties]()["paths"]
verts = path[:vertices]
xmin, ymin = minimum(verts, 1)
xmax, ymax = maximum(verts, 1)
expand_extrema!(sp, xmin, xmax, ymin, ymax)
end
end
if st == :shape
@@ -871,11 +876,13 @@ end
function py_compute_axis_minval(axis::Axis)
# compute the smallest absolute value for the log scale's linear threshold
minval = 1.0
sp = axis.sp
for series in series_list(axis.sp)
v = series.d[axis[:letter]]
if !isempty(v)
minval = min(minval, minimum(abs(v)))
sps = axis.sps
for sp in sps
for series in series_list(sp)
v = series.d[axis[:letter]]
if !isempty(v)
minval = min(minval, minimum(abs(v)))
end
end
end
@@ -980,8 +987,15 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# axis attributes
for letter in (:x, :y, :z)
axissym = Symbol(letter, :axis)
axis = sp[axissym]
haskey(ax, axissym) || continue
axis = sp[axissym]
pyaxis = ax[axissym]
if axis[:mirror] && letter != :z
pos = letter == :x ? "top" : "right"
pyaxis[:set_label_position](pos) # the guides
pyaxis[:set_ticks_position]("both") # the hash marks
pyaxis[Symbol(:tick_, pos)]() # the tick labels
end
py_set_scale(ax, axis)
py_set_lims(ax, axis)
py_set_ticks(ax, get_ticks(axis), letter)
@@ -989,14 +1003,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
if get(axis.d, :flip, false)
ax[Symbol("invert_", letter, "axis")]()
end
ax[axissym][:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefont].pointsize))
pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefont].pointsize))
for lab in ax[Symbol("get_", letter, "ticklabels")]()
lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfont].pointsize))
lab[:set_rotation](axis[:rotation])
end
if sp[:grid]
fgcolor = py_color(sp[:foreground_color_grid])
ax[axissym][:grid](true, color = fgcolor)
pyaxis[:grid](true, color = fgcolor)
ax[:set_axisbelow](true)
end
py_set_axis_colors(ax, axis)
@@ -1184,14 +1198,14 @@ const _pyplot_mimeformats = Dict(
for (mime, fmt) in _pyplot_mimeformats
@eval function _writemime(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PyPlotBackend})
@eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PyPlotBackend})
fig = plt.o
fig.o[:canvas][:print_figure](
fig[:canvas][:print_figure](
io,
format=$fmt,
# bbox_inches = "tight",
# figsize = map(px2inch, plt[:size]),
facecolor = fig.o[:get_facecolor](),
facecolor = fig[:get_facecolor](),
edgecolor = "none",
dpi = plt[:dpi]
)
+6 -8
View File
@@ -39,7 +39,7 @@ end
# -------------------------------
@compat const _qwtAliases = KW(
const _qwtAliases = KW(
:bins => :heatmap_n,
:fillrange => :fillto,
:linewidth => :width,
@@ -133,7 +133,7 @@ function updateLimsAndTicks(plt::Plot{QwtBackend}, d::KW, isx::Bool)
w = plt.o.widget
axisid = Qwt.QWT.QwtPlot[isx ? :xBottom : :yLeft]
if typeof(lims) <: @compat(Union{Tuple,AVec}) && length(lims) == 2
if typeof(lims) <: Union{Tuple,AVec} && length(lims) == 2
if isx
plt.o.autoscale_x = false
else
@@ -211,14 +211,14 @@ function createQwtAnnotation(plt::Plot, x, y, val::PlotText)
marker[:attach](plt.o.widget)
end
function createQwtAnnotation(plt::Plot, x, y, val::@compat(AbstractString))
function createQwtAnnotation(plt::Plot, x, y, val::AbstractString)
marker = Qwt.QWT.QwtPlotMarker()
marker[:setValue](x, y)
marker[:setLabel](Qwt.QWT.QwtText(val))
marker[:attach](plt.o.widget)
end
function _add_annotations{X,Y,V}(plt::Plot{QwtBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
function _add_annotations{X,Y,V}(plt::Plot{QwtBackend}, anns::AVec{Tuple{X,Y,V}})
for ann in anns
createQwtAnnotation(plt, ann...)
end
@@ -242,8 +242,6 @@ end
# -------------------------------
# savepng(::QwtBackend, plt::AbstractPlot, fn::@compat(AbstractString), args...) = Qwt.savepng(plt.o, fn)
# -------------------------------
# # create the underlying object (each backend will do this differently)
@@ -282,13 +280,13 @@ end
# ----------------------------------------------------------------
function Base.writemime(io::IO, ::MIME"image/png", plt::Plot{QwtBackend})
function Base.show(io::IO, ::MIME"image/png", plt::Plot{QwtBackend})
Qwt.refresh(plt.o)
Qwt.savepng(plt.o, "/tmp/dfskjdhfkh.png")
write(io, readall("/tmp/dfskjdhfkh.png"))
end
# function Base.writemime(io::IO, ::MIME"image/png", subplt::Subplot{QwtBackend})
# function Base.show(io::IO, ::MIME"image/png", subplt::Subplot{QwtBackend})
# for plt in subplt.plts
# Qwt.refresh(plt.o)
# end
+1 -1
View File
@@ -67,7 +67,7 @@ end
# "image/png" => "png",
# "application/postscript" => "ps",
# "image/svg+xml" => "svg"
function _writemime(io::IO, ::MIME"image/png", plt::Plot{[PkgName]Backend})
function _show(io::IO, ::MIME"image/png", plt::Plot{[PkgName]Backend})
end
# Display/show the plot (open a GUI window, or browser page, for example).
+3 -3
View File
@@ -112,7 +112,7 @@ end
# -------------------------------
# since this is such a hack, it's only callable using `png`... should error during normal `writemime`
# since this is such a hack, it's only callable using `png`... should error during normal `show`
function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString)
fn = addExtension(fn, "png")
@@ -121,7 +121,7 @@ function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString)
gui(plt)
# @osx_only begin
@compat @static if is_apple()
@static if is_apple()
# BEGIN HACK
# wait while the plot gets drawn
@@ -148,7 +148,7 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
rebuildUnicodePlot!(plt, div(w, 10), div(h, 20))
end
function _writemime(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
unicodeplots_rebuild(plt)
map(show, plt.o)
nothing
+4 -4
View File
@@ -20,13 +20,13 @@ function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr
end
function open_browser_window(filename::AbstractString)
@compat @static if is_apple()
@static if is_apple()
return run(`open $(filename)`)
end
@compat @static if is_linux()
@static if is_linux()
return run(`xdg-open $(filename)`)
end
@compat @static if is_windows()
@static if is_windows()
return run(`$(ENV["COMSPEC"]) /c start $(filename)`)
end
warn("Unknown OS... cannot open browser window.")
@@ -51,7 +51,7 @@ function html_to_png(html_fn, png_fn, w, h)
run(`wkhtmltoimage -f png -q --width $w --height $h --disable-smart-width $html_fn $png_fn`)
end
function writemime_png_from_html(io::IO, plt::AbstractPlot)
function show_png_from_html(io::IO, plt::AbstractPlot)
# write html to a temporary file
html_fn = write_temp_html(plt)
+7 -7
View File
@@ -44,13 +44,13 @@ end
## dictionaries for conversion of Plots.jl names to Winston ones.
@compat const winston_linestyle = KW(:solid=>"solid",
const winston_linestyle = KW(:solid=>"solid",
:dash=>"dash",
:dot=>"dotted",
:dashdot=>"dotdashed"
)
@compat const winston_marker = KW(:none=>".",
const winston_marker = KW(:none=>".",
:rect => "square",
:circle=>"circle",
:diamond=>"diamond",
@@ -185,7 +185,7 @@ end
# ----------------------------------------------------------------
@compat const _winstonNames = KW(
const _winstonNames = KW(
:xlims => :xrange,
:ylims => :yrange,
:xscale => :xlog,
@@ -213,11 +213,11 @@ end
# ----------------------------------------------------------------
function createWinstonAnnotationObject(plt::Plot{WinstonBackend}, x, y, val::@compat(AbstractString))
function createWinstonAnnotationObject(plt::Plot{WinstonBackend}, x, y, val::AbstractString)
Winston.text(x, y, val)
end
function _add_annotations{X,Y,V}(plt::Plot{WinstonBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
function _add_annotations{X,Y,V}(plt::Plot{WinstonBackend}, anns::AVec{Tuple{X,Y,V}})
for ann in anns
createWinstonAnnotationObject(plt, ann...)
end
@@ -238,10 +238,10 @@ function addWinstonLegend(plt::Plot, wplt)
end
end
function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{WinstonBackend})
function Base.show(io::IO, ::MIME"image/png", plt::AbstractPlot{WinstonBackend})
window, canvas, wplt = getWinstonItems(plt)
addWinstonLegend(plt, wplt)
writemime(io, "image/png", wplt)
show(io, "image/png", wplt)
end
+7 -4
View File
@@ -47,7 +47,7 @@ end
"get an array of tuples of points on a circle with radius `r`"
function partialcircle(start_θ, end_θ, n = 20, r=1)
@compat(Tuple{Float64,Float64})[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]
Tuple{Float64,Float64}[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]
end
"interleave 2 vectors into each other (like a zipper's teeth)"
@@ -119,6 +119,8 @@ const _shape_keys = Symbol[
:star8,
:vline,
:hline,
:+,
:x,
]
const _shapes = KW(
@@ -209,8 +211,9 @@ function rotate!(shape::Shape, Θ::Real, c = center(shape))
x, y = shape_coords(shape)
cx, cy = c
for i=1:length(x)
x[i] = rotate_x(x[i], y[i], Θ, cx, cy)
y[i] = rotate_y(x[i], y[i], Θ, cx, cy)
xi = rotate_x(x[i], y[i], Θ, cx, cy)
yi = rotate_y(x[i], y[i], Θ, cx, cy)
x[i], y[i] = xi, yi
end
shape
end
@@ -472,7 +475,7 @@ type BezierCurve{T <: FixedSizeArrays.Vec}
control_points::Vector{T}
end
@compat function (bc::BezierCurve)(t::Real)
function (bc::BezierCurve)(t::Real)
p = zero(P2)
n = length(bc.control_points)-1
for i in 0:n
+1 -1
View File
@@ -252,7 +252,7 @@ PlotExample("DataFrames",
iris = RDatasets.dataset("datasets", "iris")
scatter(iris, :SepalLength, :SepalWidth, group=:Species,
title = "My awesome plot", xlabel = "Length", ylabel = "Width",
marker = (0.5, [:+ :h :star7], 12), bg=RGB(.2,.2,.2))
marker = (0.5, [:cross :hex :star7], 12), bg=RGB(.2,.2,.2))
end)]
),
+43 -25
View File
@@ -9,10 +9,10 @@ to_pixels(m::AbsoluteLength) = m.value / 0.254
const _cbar_width = 5mm
@compat Base.:.*(m::Measure, n::Number) = m * n
@compat Base.:.*(n::Number, m::Measure) = m * n
@compat Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
@compat Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a)
Base.:.*(m::Measure, n::Number) = m * n
Base.:.*(n::Number, m::Measure) = m * n
Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a)
Base.zero(::Type{typeof(mm)}) = 0mm
Base.one(::Type{typeof(mm)}) = 1mm
Base.typemin(::typeof(mm)) = -Inf*mm
@@ -20,15 +20,15 @@ Base.typemax(::typeof(mm)) = Inf*mm
Base.convert{F<:AbstractFloat}(::Type{F}, l::AbsoluteLength) = convert(F, l.value)
# TODO: these are unintuitive and may cause tricky bugs
# @compat Base.:+(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 + m2.value))
# @compat Base.:+(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (1 + m1.value))
# @compat Base.:-(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 - m2.value))
# @compat Base.:-(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (m1.value - 1))
# Base.:+(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 + m2.value))
# Base.:+(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (1 + m1.value))
# Base.:-(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 - m2.value))
# Base.:-(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (m1.value - 1))
@compat Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
@compat Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
@compat Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
@compat Base.:/(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value / m1.value)
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
Base.:/(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value / m1.value)
Base.zero(::Type{typeof(pct)}) = 0pct
@@ -44,11 +44,11 @@ right(bbox::BoundingBox) = left(bbox) + width(bbox)
bottom(bbox::BoundingBox) = top(bbox) + height(bbox)
Base.size(bbox::BoundingBox) = (width(bbox), height(bbox))
# @compat Base.:*{T,N}(m1::Length{T,N}, m2::Length{T,N}) = Length{T,N}(m1.value * m2.value)
# Base.:*{T,N}(m1::Length{T,N}, m2::Length{T,N}) = Length{T,N}(m1.value * m2.value)
ispositive(m::Measure) = m.value > 0
# union together bounding boxes
@compat function Base.:+(bb1::BoundingBox, bb2::BoundingBox)
function Base.:+(bb1::BoundingBox, bb2::BoundingBox)
# empty boxes don't change the union
ispositive(width(bb1)) || return bb2
ispositive(height(bb1)) || return bb2
@@ -239,7 +239,9 @@ function GridLayout(dims...;
# convert(Vector{Float64}, widths),
# convert(Vector{Float64}, heights),
KW(kw))
fill!(grid, EmptyLayout(layout))
for i in eachindex(grid)
grid[i] = EmptyLayout(layout)
end
layout
end
@@ -311,7 +313,6 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0
minpad_top = map(toppad, layout.grid)
minpad_right = map(rightpad, layout.grid)
minpad_bottom = map(bottompad, layout.grid)
# @show minpad_left minpad_top minpad_right minpad_bottom
# get the max horizontal (left and right) padding over columns,
# and max vertical (bottom and top) padding over rows
@@ -320,7 +321,6 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0
pad_top = maximum(minpad_top, 2)
pad_right = maximum(minpad_right, 1)
pad_bottom = maximum(minpad_bottom, 2)
# @show pad_left pad_top pad_right pad_bottom
# make sure the perimeter match the parent
pad_left[1] = max(pad_left[1], minimum_perimeter[1])
@@ -331,22 +331,18 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0
# scale this up to the total padding in each direction
total_pad_horizontal = sum(pad_left + pad_right)
total_pad_vertical = sum(pad_top + pad_bottom)
# @show total_pad_horizontal total_pad_vertical
# now we can compute the total plot area in each direction
total_plotarea_horizontal = width(layout) - total_pad_horizontal
total_plotarea_vertical = height(layout) - total_pad_vertical
# @show total_plotarea_horizontal total_plotarea_vertical
# recompute widths/heights
layout.widths = recompute_lengths(layout.widths)
layout.heights = recompute_lengths(layout.heights)
# @show layout.widths layout.heights
# normalize widths/heights so they sum to 1
# denom_w = sum(layout.widths)
# denom_h = sum(layout.heights)
# @show layout.widths layout.heights denom_w, denom_h
# we have all the data we need... lets compute the plot areas and set the bounding boxes
for r=1:nr, c=1:nc
@@ -387,7 +383,6 @@ end
function update_inset_bboxes!(plt::Plot)
for sp in plt.inset_subplots
p_area = Measures.resolve(plotarea(sp.parent), sp[:relative_bbox])
# @show bbox(sp.parent) sp[:relative_bbox] p_area
plotarea!(sp, p_area)
bbox!(sp, bbox(
@@ -597,7 +592,7 @@ function create_grid(expr::Expr)
create_grid_curly(expr)
else
# if it's something else, just return that (might be an existing layout?)
expr
esc(expr)
end
end
@@ -639,7 +634,6 @@ function create_grid_curly(expr::Expr)
for (i,arg) in enumerate(expr.args[2:end])
add_layout_pct!(kw, arg, i, length(expr.args)-1)
end
# @show kw
:(EmptyLayout(label = $(QuoteNode(s)), width = $(get(kw, :w, QuoteNode(:auto))), height = $(get(kw, :h, QuoteNode(:auto)))))
end
@@ -654,14 +648,23 @@ end
# -------------------------------------------------------------------------
# make all reference the same axis extrema/values
# make all reference the same axis extrema/values.
# merge subplot lists.
function link_axes!(axes::Axis...)
a1 = axes[1]
for i=2:length(axes)
a2 = axes[i]
expand_extrema!(a1, extrema(a2))
for k in (:extrema, :discrete_values, :continuous_values, :discrete_map)
a2[k] = a1[k]
end
# make a2's subplot list refer to a1's and add any missing values
sps2 = a2.sps
for sp in sps2
sp in a1.sps || push!(a1.sps, sp)
end
a2.sps = a1.sps
end
end
@@ -709,3 +712,18 @@ function link_axes!(layout::GridLayout, link::Symbol)
link_axes!(l, link)
end
end
# -------------------------------------------------------------------------
"Adds a new, empty subplot overlayed on top of `sp`, with a mirrored y-axis and linked x-axis."
function twinx(sp::Subplot)
sp[:right_margin] = max(sp[:right_margin], 30px)
plot!(sp.plt, inset = (sp[:subplot_index], bbox(0,0,1,1)))
twinsp = sp.plt.subplots[end]
twinsp[:yaxis][:mirror] = true
twinsp[:background_color_inside] = RGBA{Float64}(0,0,0,0)
link_axes!(sp[:xaxis], twinsp[:xaxis])
twinsp
end
twinx(plt::Plot = current()) = twinx(plt[1])
+69 -46
View File
@@ -5,7 +5,7 @@ defaultOutputFormat(plt::Plot) = "png"
function png(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "png")
io = open(fn, "w")
writemime(io, MIME("image/png"), plt)
show(io, MIME("image/png"), plt)
close(io)
end
png(fn::AbstractString) = png(current(), fn)
@@ -13,7 +13,7 @@ png(fn::AbstractString) = png(current(), fn)
function svg(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "svg")
io = open(fn, "w")
writemime(io, MIME("image/svg+xml"), plt)
show(io, MIME("image/svg+xml"), plt)
close(io)
end
svg(fn::AbstractString) = svg(current(), fn)
@@ -22,7 +22,7 @@ svg(fn::AbstractString) = svg(current(), fn)
function pdf(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
writemime(io, MIME("application/pdf"), plt)
show(io, MIME("application/pdf"), plt)
close(io)
end
pdf(fn::AbstractString) = pdf(current(), fn)
@@ -31,16 +31,23 @@ pdf(fn::AbstractString) = pdf(current(), fn)
function ps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "ps")
io = open(fn, "w")
writemime(io, MIME("application/postscript"), plt)
show(io, MIME("application/postscript"), plt)
close(io)
end
ps(fn::AbstractString) = ps(current(), fn)
function eps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "eps")
io = open(fn, "w")
writemime(io, MIME("image/eps"), plt)
close(io)
end
eps(fn::AbstractString) = eps(current(), fn)
function tex(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "tex")
io = open(fn, "w")
writemime(io, MIME("application/x-tex"), plt)
show(io, MIME("application/x-tex"), plt)
close(io)
end
tex(fn::AbstractString) = tex(current(), fn)
@@ -49,11 +56,12 @@ tex(fn::AbstractString) = tex(current(), fn)
# ----------------------------------------------------------------
@compat const _savemap = Dict(
const _savemap = Dict(
"png" => png,
"svg" => svg,
"pdf" => pdf,
"ps" => ps,
"eps" => eps,
"tex" => tex,
)
@@ -129,26 +137,26 @@ const _best_html_output_type = KW(
)
# a backup for html... passes to svg or png depending on the html_output_format arg
function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)
function Base.show(io::IO, ::MIME"text/html", plt::Plot)
output_type = Symbol(plt.attr[:html_output_format])
if output_type == :auto
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
end
if output_type == :png
# info("writing png to html output")
print(io, "<img src=\"data:image/png;base64,", base64encode(writemime, MIME("image/png"), plt), "\" />")
print(io, "<img src=\"data:image/png;base64,", base64encode(show, MIME("image/png"), plt), "\" />")
elseif output_type == :svg
# info("writing svg to html output")
writemime(io, MIME("image/svg+xml"), plt)
show(io, MIME("image/svg+xml"), plt)
elseif output_type == :txt
writemime(io, MIME("text/plain"), plt)
show(io, MIME("text/plain"), plt)
else
error("only png or svg allowed. got: $output_type")
end
end
function _writemime(io::IO, m, plt::Plot)
warn("_writemime is not defined for this backend. m=", string(m))
function _show(io::IO, m, plt::Plot)
warn("_show is not defined for this backend. m=", string(m))
end
function _display(plt::Plot)
warn("_display is not defined for this backend.")
@@ -156,9 +164,9 @@ end
# for writing to io streams... first prepare, then callback
for mime in keys(_mimeformats)
@eval function Base.writemime(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
prepare_output(plt)
_writemime(io, m, plt)
_show(io, m, plt)
end
end
@@ -168,7 +176,7 @@ end
if is_installed("FileIO")
@eval import FileIO
function _writemime(io::IO, ::MIME"image/png", plt::Plot)
function _show(io::IO, ::MIME"image/png", plt::Plot)
fn = tempname()
# first save a pdf file
@@ -192,12 +200,12 @@ end
# function html_output_format(fmt)
# if fmt == "png"
# @eval function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)
# print(io, "<img src=\"data:image/png;base64,", base64(writemime, MIME("image/png"), plt), "\" />")
# @eval function Base.show(io::IO, ::MIME"text/html", plt::Plot)
# print(io, "<img src=\"data:image/png;base64,", base64(show, MIME("image/png"), plt), "\" />")
# end
# elseif fmt == "svg"
# @eval function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)
# writemime(io, MIME("image/svg+xml"), plt)
# @eval function Base.show(io::IO, ::MIME"text/html", plt::Plot)
# show(io, MIME("image/svg+xml"), plt)
# end
# else
# error("only png or svg allowed. got: $fmt")
@@ -210,7 +218,7 @@ end
# IJulia
# ---------------------------------------------------------
const _ijulia_output = Compat.ASCIIString["text/html"]
const _ijulia_output = String["text/html"]
function setup_ijulia()
# override IJulia inline display
@@ -225,12 +233,12 @@ function setup_ijulia()
end
function IJulia.display_dict(plt::Plot)
global _ijulia_output
Dict{Compat.ASCIIString, ByteString}(_ijulia_output[1] => sprint(writemime, _ijulia_output[1], plt))
Dict{String, String}(_ijulia_output[1] => sprint(show, _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)
function Base.show(io::IO, m::MIME"text/plain", plt::Plot)
show(io, MIME("text/html"), plt)
end
end
set_ijulia_output("text/html")
@@ -243,34 +251,49 @@ end
function setup_atom()
# @require Atom begin
if isatom() && get(ENV, "PLOTS_USE_ATOM_PLOTPANE", false) in (true, 1, "1", "true", "yes")
if isatom()
# @eval import Atom, Media
@eval import Atom
# # connects the render function
# for T in (GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend)
# Atom.Media.media(Plot{T}, Atom.Media.Plot)
# end
Atom.Media.media(Plot, Atom.Media.Graphical)
# Atom.Media.media{T <: Union{GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend}}(Plot{T}, Atom.Media.Plot)
# Atom.displaysize(::Plot) = (535, 379)
# Atom.displaytitle(plt::Plot) = "Plots.jl (backend: $(backend(plt)))"
# this is like "display"... sends an html div with the plot to the PlotPane
function Atom.Media.render(pane::Atom.PlotPane, plt::Plot)
@show "here"
Atom.Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt))))
# default text/plain passes to html... handles Interact issues
function Base.show(io::IO, m::MIME"text/plain", plt::Plot)
show(io, MIME("text/html"), plt)
end
# # force text/plain to output to the PlotPane
# function Base.writemime(io::IO, ::MIME"text/plain", plt::Plot)
# # writemime(io::IO, MIME("text/html"), plt)
# Atom.Media.render(pane)
# end
# for inline values, display the plot (gui) and return a graph icon
function Atom.Media.render(::Atom.Inline, plt::Plot)
# info("using Media.render")
display(plt)
Atom.icon("graph")
end
# function Atom.Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyBackend})
# html = Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt))))
# end
if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", false) in (true, 1, "1", "true", "yes")
# # connects the render function
# for T in (GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend)
# Atom.Media.media(Plot{T}, Atom.Media.Plot)
# end
Atom.Media.media(Plot, Atom.Media.Graphical)
# Atom.Media.media{T <: Union{GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend}}(Plot{T}, Atom.Media.Plot)
# Atom.displaysize(::Plot) = (535, 379)
# Atom.displaytitle(plt::Plot) = "Plots.jl (backend: $(backend(plt)))"
# this is like "display"... sends an html div with the plot to the PlotPane
function Atom.Media.render(pane::Atom.PlotPane, plt::Plot)
@show "here"
Atom.Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt))))
end
# # force text/plain to output to the PlotPane
# function Base.show(io::IO, ::MIME"text/plain", plt::Plot)
# # show(io::IO, MIME("text/html"), plt)
# Atom.Media.render(pane)
# end
# function Atom.Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyBackend})
# html = Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt))))
# end
end
end
end
+10 -3
View File
@@ -13,7 +13,7 @@ function _expand_seriestype_array(d::KW, args)
delete!(d, :seriestype)
RecipeData[begin
dc = copy(d)
dc[:seriestype] = sts[r,:]
dc[:seriestype] = sts[r:r,:]
RecipeData(dc, args)
end for r=1:size(sts,1)]
else
@@ -95,6 +95,7 @@ function _process_userrecipe(plt::Plot, kw_list::Vector{KW}, recipedata::RecipeD
# when the arg tuple is empty, that means there's nothing left to recursively
# process... finish up and add to the kw_list
kw = recipedata.d
preprocessArgs!(kw)
_preprocess_userrecipe(kw)
warnOnUnsupported_scales(plt.backend, kw)
@@ -183,6 +184,7 @@ function _process_plotrecipe(plt::Plot, kw::KW, kw_list::Vector{KW}, still_to_pr
st = kw[:seriestype] = get(_typeAliases, st, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
for data in datalist
preprocessArgs!(data.d)
if data.d[:seriestype] == st
error("Plot recipe $st returned the same seriestype: $(data.d)")
end
@@ -242,12 +244,13 @@ function _plot_setup(plt::Plot, d::KW, kw_list::Vector{KW})
end
sp = Subplot(backend(), parent=parent)
sp.plt = plt
sp.attr[:relative_bbox] = bb
sp.attr[:subplot_index] = length(plt.subplots)
push!(plt.subplots, sp)
push!(plt.inset_subplots, sp)
sp.attr[:relative_bbox] = bb
sp.attr[:subplot_index] = length(plt.subplots)
end
end
plt[:inset_subplots] = nothing
end
function _subplot_setup(plt::Plot, d::KW, kw_list::Vector{KW})
@@ -388,6 +391,10 @@ function _process_seriesrecipe(plt::Plot, d::KW)
# assuming there was no error, recursively apply the series recipes
for data in datalist
if isa(data, RecipeData)
preprocessArgs!(data.d)
if data.d[:seriestype] == st
error("The seriestype didn't change in series recipe $st. This will cause a StackOverflow.")
end
_process_seriesrecipe(plt, data.d)
else
warn("Unhandled recipe: $(data)")
+10 -1
View File
@@ -148,7 +148,7 @@ end
# 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::Tuple)
# d[:plot_object] = plt
d[:plot_object] = plt
# --------------------------------
# "USER RECIPES"
@@ -156,6 +156,9 @@ function _plot!(plt::Plot, d::KW, args::Tuple)
kw_list = _process_userrecipes(plt, d, args)
# info(1)
# map(DD, kw_list)
# --------------------------------
# "PLOT RECIPES"
@@ -172,6 +175,9 @@ function _plot!(plt::Plot, d::KW, args::Tuple)
_process_plotrecipe(plt, next_kw, kw_list, still_to_process)
end
# info(2)
# map(DD, kw_list)
# --------------------------------
# Plot/Subplot/Layout setup
# --------------------------------
@@ -184,6 +190,9 @@ function _plot!(plt::Plot, d::KW, args::Tuple)
# --------------------------------
# "SERIES RECIPES"
# --------------------------------
# info(3)
# map(DD, kw_list)
for kw in kw_list
sp::Subplot = kw[:subplot]
+9 -9
View File
@@ -9,7 +9,7 @@ function _precompile_()
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{Union{String, 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},))
@@ -81,13 +81,13 @@ function _precompile_()
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.extractGroupArgs, (Array{Union{String, 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.discrete_value!, (Plots.Axis, Array{Union{String, 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,))
@@ -121,11 +121,11 @@ function _precompile_()
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.plot, (Array{Any, 1}, Array{Union{String, ASCIIString}, 1}, Array{Union{String, 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.heatmap, (Array{Any, 1}, Array{Union{String, 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},))
@@ -156,7 +156,7 @@ function _precompile_()
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.getExtension, (String,))
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},))
@@ -250,7 +250,7 @@ function _precompile_()
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.png, (Plots.Plot{Plots.PyPlotBackend}, String,))
precompile(Plots.processFillArg, (Base.Dict{Symbol, Any}, Symbol,))
precompile(Plots.allShapes, (Plots.Shape,))
precompile(Plots.handleColors!, (Base.Dict{Symbol, Any}, Plots.Stroke, Symbol,))
@@ -300,7 +300,7 @@ function _precompile_()
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.compute_xyz, (Array{Union{String, ASCIIString}, 1}, Array{Union{String, 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},))
@@ -309,7 +309,7 @@ function _precompile_()
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.addExtension, (String, 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}}},))
+29 -5
View File
@@ -202,6 +202,7 @@ end
function make_steps(x, y, st)
n = length(x)
n == 0 && return zeros(0),zeros(0)
newx, newy = zeros(2n-1), zeros(2n-1)
for i=1:n
idx = 2i-1
@@ -261,19 +262,23 @@ end
# ---------------------------------------------------------------------------
# sticks
sticks_fillfrom(fr::Void, i::Integer) = 0.0
sticks_fillfrom(fr::Number, i::Integer) = fr
sticks_fillfrom(fr::AVec, i::Integer) = fr[mod1(i, length(fr))]
# create vertical line segments from fill
@recipe function f(::Type{Val{:sticks}}, x, y, z)
n = length(x)
fr = d[:fillrange]
if fr == nothing
yaxis = d[:subplot][:yaxis]
fr = if yaxis[:scale] == :identity
0.0
else
min(axis_limits(yaxis)[1], minimum(y))
end
end
newx, newy = zeros(3n), zeros(3n)
for i=1:n
rng = 3i-2:3i
newx[rng] = [x[i], x[i], NaN]
newy[rng] = [sticks_fillfrom(fr,i), y[i], NaN]
newy[rng] = [cycle(fr,i), y[i], NaN]
end
x := newx
y := newy
@@ -405,6 +410,9 @@ end
xseg, yseg = yseg, xseg
end
# reset orientation
orientation := default(:orientation)
x := xseg.pts
y := yseg.pts
seriestype := :shape
@@ -950,3 +958,19 @@ function abline!(plt::Plot, a, b; kw...)
end
abline!(args...; kw...) = abline!(current(), args...; kw...)
# -------------------------------------------------
# Dates
@recipe function f{T<:AbstractArray{Date}}(::Type{T}, dts::T)
date_formatter = dt -> string(convert(Date, dt))
xformatter := date_formatter
map(dt->convert(Int,dt), dts)
end
@recipe function f{T<:AbstractArray{DateTime}}(::Type{T}, dts::T)
date_formatter = dt -> string(convert(DateTime, dt))
xformatter := date_formatter
map(dt->convert(Int,dt), dts)
end
+23 -24
View File
@@ -6,12 +6,12 @@
# This should cut down on boilerplate code and allow more focused dispatch on type
# note: returns meta information... mainly for use with automatic labeling from DataFrames for now
typealias FuncOrFuncs @compat(Union{Function, AVec{Function}})
typealias FuncOrFuncs Union{Function, AVec{Function}}
all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none))
# missing
convertToAnyVector(v::@compat(Void), d::KW) = Any[nothing], nothing
convertToAnyVector(v::Void, d::KW) = Any[nothing], nothing
# fixed number of blank series
convertToAnyVector(n::Integer, d::KW) = Any[zeros(0) for i in 1:n], nothing
@@ -20,7 +20,7 @@ convertToAnyVector(n::Integer, d::KW) = Any[zeros(0) for i in 1:n], nothing
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
convertToAnyVector{T<:AbstractString}(v::AVec{T}, d::KW) = Any[v], nothing
function convertToAnyVector(v::AMat, d::KW)
if all3D(d)
@@ -125,21 +125,19 @@ immutable SliceIt end
mx = length(xs)
my = length(ys)
mz = length(zs)
# ret = Any[]
for i in 1:max(mx, my, mz)
# add a new series
di = copy(d)
xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]
# @show i, typeof((xi, yi, zi))
di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi)
# @show i, typeof((di[:x], di[:y], di[:z]))
if mx > 0 && my > 0 && mz > 0
for i in 1:max(mx, my, mz)
# add a new series
di = copy(d)
xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]
di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi)
# handle fillrange
fr = fillranges[mod1(i,mf)]
di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr
# handle fillrange
fr = fillranges[mod1(i,mf)]
di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr
# @show i, di[:x], di[:y], di[:z]
push!(series_list, RecipeData(di, ()))
push!(series_list, RecipeData(di, ()))
end
end
nothing # don't add a series for the main block
end
@@ -210,7 +208,7 @@ end
# # 1 argument
# # --------------------------------------------------------------------
@recipe f(n::Integer) = n, n, n
@recipe f(n::Integer) = is3d(get(d,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
# return a surface if this is a 3d plot, otherwise let it be sliced up
@recipe function f{T<:Number}(mat::AMat{T})
@@ -273,14 +271,15 @@ end
end
end
#
#
# # function without range... use the current range of the x-axis
# @recipe function f(f::FuncOrFuncs)
# plt = d[:plot_object]
# f, xmin(plt), xmax(plt)
# end
# function without range... use the current range of the x-axis
@recipe function f(f::FuncOrFuncs)
plt = d[:plot_object]
xmin,xmax = axis_limits(plt[1][:xaxis])
f, xmin, xmax
end
#
# # --------------------------------------------------------------------
+3 -1
View File
@@ -34,11 +34,13 @@ type Subplot{T<:AbstractBackend} <: AbstractLayout
plt # the enclosing Plot object (can't give it a type because of no forward declarations)
end
Base.show(io::IO, sp::Subplot) = print(io, "Subplot{$(sp[:subplot_index])}")
# -----------------------------------------------------------
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
type Axis
sp::Subplot
sps::Vector{Subplot}
d::KW
end
+66 -7
View File
@@ -243,16 +243,17 @@ Base.cycle(v, idx::Int) = v
Base.cycle(v::AVec, indices::AVec{Int}) = map(i -> cycle(v,i), indices)
Base.cycle(v::AMat, indices::AVec{Int}) = map(i -> cycle(v,i), indices)
Base.cycle(v, idx::AVec{Int}) = v
Base.cycle(v, indices::AVec{Int}) = fill(v, length(indices))
Base.cycle(grad::ColorGradient, idx::Int) = cycle(grad.colors, idx)
Base.cycle(grad::ColorGradient, indices::AVec{Int}) = cycle(grad.colors, indices)
makevec(v::AVec) = v
makevec{T}(v::T) = T[v]
"duplicate a single value, or pass the 2-tuple through"
maketuple(x::Real) = (x,x)
maketuple{T,S}(x::@compat(Tuple{T,S})) = x
maketuple{T,S}(x::Tuple{T,S}) = x
mapFuncOrFuncs(f::Function, u::AVec) = map(f, u)
mapFuncOrFuncs(fs::AVec{Function}, u::AVec) = [map(f, u) for f in fs]
@@ -386,13 +387,12 @@ isvertical(d::KW) = get(d, :orientation, :vertical) in (:vertical, :v, :vert)
isvertical(series::Series) = isvertical(series.d)
# ticksType{T<:Real,S<:Real}(ticks::@compat(Tuple{T,S})) = :limits
ticksType{T<:Real}(ticks::AVec{T}) = :ticks
ticksType{T<:AbstractString}(ticks::AVec{T}) = :labels
ticksType{T<:AVec,S<:AVec}(ticks::@compat(Tuple{T,S})) = :ticks_and_labels
ticksType{T<:AVec,S<:AVec}(ticks::Tuple{T,S}) = :ticks_and_labels
ticksType(ticks) = :invalid
limsType{T<:Real,S<:Real}(lims::@compat(Tuple{T,S})) = :limits
limsType{T<:Real,S<:Real}(lims::Tuple{T,S}) = :limits
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
limsType(lims) = :invalid
@@ -445,7 +445,8 @@ end
# for example: PyPlot sends rows to y, so transpose_on_match should be true
function transpose_z(d, z, transpose_on_match::Bool = true)
if d[:match_dimensions] == transpose_on_match
z'
# z'
permutedims(z, [2,1])
else
z
end
@@ -476,7 +477,7 @@ end
# ---------------------------------------------------------------
wraptuple(x::@compat(Tuple)) = x
wraptuple(x::Tuple) = x
wraptuple(x) = (x,)
trueOrAllTrue(f::Function, x::AbstractArray) = all(f, x)
@@ -667,6 +668,64 @@ end
Base.setindex!{X,Y}(plt::Plot, xy::Tuple{X,Y}, i::Integer) = setxy!(plt, xy, i)
Base.setindex!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) = setxyz!(plt, xyz, i)
# -------------------------------------------------------
# operate on individual series
function push_x!(series::Series, xi)
push!(series[:x], xi)
expand_extrema!(series[:subplot][:xaxis], xi)
return
end
function push_y!(series::Series, yi)
push!(series[:y], yi)
expand_extrema!(series[:subplot][:yaxis], yi)
return
end
function push_z!(series::Series, zi)
push!(series[:z], zi)
expand_extrema!(series[:subplot][:zaxis], zi)
return
end
function Base.push!(series::Series, yi)
x = extendSeriesByOne(series[:x])
expand_extrema!(series[:subplot][:xaxis], x[end])
series[:x] = x
push_y!(series, yi)
end
Base.push!(series::Series, xi, yi) = (push_x!(series,xi); push_y!(series,yi))
Base.push!(series::Series, xi, yi, zi) = (push_x!(series,xi); push_y!(series,yi); push_z!(series,zi))
# -------------------------------------------------------
function update!(series::Series; kw...)
d = KW(kw)
preprocessArgs!(d)
for (k,v) in d
if haskey(_series_defaults, k)
series[k] = v
else
warn("unused key $k in series update")
end
end
_series_updated(series[:subplot].plt, series)
series
end
function update!(sp::Subplot; kw...)
d = KW(kw)
preprocessArgs!(d)
for (k,v) in d
if haskey(_subplot_defaults, k)
sp[k] = v
else
warn("unused key $k in subplot update")
end
end
sp
end
# -------------------------------------------------------
# push/append for one series
-8
View File
@@ -1,17 +1,9 @@
julia 0.4
RecipesBase
PlotUtils
StatPlots
Reexport
Measures
Showoff
FactCheck
Images
ImageMagick
@osx QuartzImageIO
GR
DataFrames
RDatasets
VisualRegressionTests
UnicodePlots
+2 -2
View File
@@ -24,7 +24,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.8.1"
const _current_plots_version = v"0.9.0"
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
@@ -45,7 +45,7 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is
# firgure out version info
G = glob(joinpath(relpath(refdir), "*"))
# @show refdir fn G
slash = (@windows ? "\\" : "/")
slash = (@static is_windows() ? "\\" : "/")
versions = map(fn -> VersionNumber(split(fn, slash)[end]), G)
versions = reverse(sort(versions))
versions = filter(v -> v <= _current_plots_version, versions)
+40 -2
View File
@@ -30,7 +30,7 @@ facts("GR") do
@fact gr() --> Plots.GRBackend()
@fact backend() --> Plots.GRBackend()
# @linux_only image_comparison_facts(:gr, skip=[], eps=img_eps)
# @static is_linux() && image_comparison_facts(:gr, skip=[], eps=img_eps)
end
facts("Plotly") do
@@ -38,7 +38,7 @@ facts("Plotly") do
@fact backend() --> Plots.PlotlyBackend()
# # until png generation is reliable on OSX, just test on linux
# @linux_only image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], eps=img_eps)
# @static is_linux() && image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], eps=img_eps)
end
@@ -85,6 +85,44 @@ facts("Axes") do
end
# tests for preprocessing recipes
# facts("recipes") do
# user recipe
# type T end
# @recipe function f(::T)
# line := (3,0.3,:red)
# marker := (20,0.5,:blue,:o)
# bg := :yellow
# rand(10)
# end
# plot(T())
# plot recipe
# @recipe function f(::Type{Val{:hiplt}},plt::Plot)
# line := (3,0.3,:red)
# marker := (20,0.5,:blue,:o)
# t := :path
# bg:=:green
# ()
# end
# plot(rand(10),t=:hiplt)
# series recipe
# @recipe function f(::Type{Val{:hi}},x,y,z)
# line := (3,0.3,:red)
# marker := (20,0.5,:blue,:o)
# t := :path
# ()
# end
# plot(rand(10),t=:hiplt)
# end
FactCheck.exitstatus()
+2 -2
View File
@@ -4,7 +4,7 @@ import SnoopCompile
# 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"))
# include(joinpath(dirname(@__FILE__), "runtests.jl"))
# end
# ----------------------------------------------------------
@@ -32,5 +32,5 @@ blacklist = ["MIME"]
pc, discards = SnoopCompile.parcel(data[end:-1:1,2], subst=subst, blacklist=blacklist)
SnoopCompile.write("/tmp/precompile", pc)
pdir = Pkg.dir("Plots")
pdir = joinpath(dirname(@__FILE__), "..")
run(`cp /tmp/precompile/precompile_Plots.jl $pdir/src/precompile.jl`)