Merge remote-tracking branch 'upstream/master'
This commit is contained in:
Josef Heinen 2018-08-10 19:57:25 +01:00
commit 5565680b53
29 changed files with 419 additions and 519 deletions

View File

@ -1,4 +1,4 @@
julia 0.7-alpha julia 0.7
RecipesBase 0.2.3 RecipesBase 0.2.3
PlotUtils 0.4.1 PlotUtils 0.4.1

View File

@ -1,5 +1,3 @@
__precompile__(true)
module Plots module Plots
using Reexport using Reexport
@ -171,6 +169,7 @@ include("arg_desc.jl")
include("plotattr.jl") include("plotattr.jl")
include("backends.jl") include("backends.jl")
include("output.jl") include("output.jl")
include("init.jl")
# --------------------------------------------------------- # ---------------------------------------------------------
@ -236,10 +235,10 @@ zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmi
"Set xticks for an existing plot" "Set xticks for an existing plot"
xticks!(v::AVec{T}; kw...) where {T<:Real} = plot!(; xticks = v, kw...) xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
"Set yticks for an existing plot" "Set yticks for an existing plot"
yticks!(v::AVec{T}; kw...) where {T<:Real} = plot!(; yticks = v, kw...) yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
xticks!( xticks!(
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...) ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
@ -274,8 +273,8 @@ let PlotOrSubplot = Union{Plot, Subplot}
global xlims!(plt::PlotOrSubplot, xmin::Real, xmax::Real; kw...) = plot!(plt; xlims = (xmin,xmax), kw...) global xlims!(plt::PlotOrSubplot, xmin::Real, xmax::Real; kw...) = plot!(plt; xlims = (xmin,xmax), kw...)
global ylims!(plt::PlotOrSubplot, ymin::Real, ymax::Real; kw...) = plot!(plt; ylims = (ymin,ymax), kw...) global ylims!(plt::PlotOrSubplot, ymin::Real, ymax::Real; kw...) = plot!(plt; ylims = (ymin,ymax), kw...)
global zlims!(plt::PlotOrSubplot, zmin::Real, zmax::Real; kw...) = plot!(plt; zlims = (zmin,zmax), kw...) global zlims!(plt::PlotOrSubplot, zmin::Real, zmax::Real; kw...) = plot!(plt; zlims = (zmin,zmax), kw...)
global xticks!(plt::PlotOrSubplot, ticks::AVec{T}; kw...) where {T<:Real} = plot!(plt; xticks = ticks, kw...) global xticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; xticks = ticks, kw...)
global yticks!(plt::PlotOrSubplot, ticks::AVec{T}; kw...) where {T<:Real} = plot!(plt; yticks = ticks, kw...) global yticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; yticks = ticks, kw...)
global xticks!(plt::PlotOrSubplot, global xticks!(plt::PlotOrSubplot,
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks,labels), kw...) ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks,labels), kw...)
global yticks!(plt::PlotOrSubplot, global yticks!(plt::PlotOrSubplot,

View File

@ -194,7 +194,7 @@ function hasgrid(arg::Symbol, letter)
if arg in _allGridSyms if arg in _allGridSyms
arg in (:all, :both, :on) || occursin(string(letter), string(arg)) arg in (:all, :both, :on) || occursin(string(letter), string(arg))
else else
warn("Unknown grid argument $arg; $(Symbol(letter, :grid)) was set to `true` instead.") @warn("Unknown grid argument $arg; $(Symbol(letter, :grid)) was set to `true` instead.")
true true
end end
end end
@ -212,7 +212,7 @@ function showaxis(arg::Symbol, letter)
if arg in _allGridSyms if arg in _allGridSyms
arg in (:all, :both, :on, :yes) || occursin(string(letter), string(arg)) arg in (:all, :both, :on, :yes) || occursin(string(letter), string(arg))
else else
warn("Unknown showaxis argument $arg; $(Symbol(letter, :showaxis)) was set to `true` instead.") @warn("Unknown showaxis argument $arg; $(Symbol(letter, :showaxis)) was set to `true` instead.")
true true
end end
end end
@ -704,7 +704,7 @@ function processLineArg(d::KW, arg)
# color # color
elseif !handleColors!(d, arg, :linecolor) elseif !handleColors!(d, arg, :linecolor)
warn("Skipped line arg $arg.") @warn("Skipped line arg $arg.")
end end
end end
@ -740,7 +740,7 @@ function processMarkerArg(d::KW, arg)
# markercolor # markercolor
elseif !handleColors!(d, arg, :markercolor) elseif !handleColors!(d, arg, :markercolor)
warn("Skipped marker arg $arg.") @warn("Skipped marker arg $arg.")
end end
end end
@ -800,7 +800,7 @@ function processGridArg!(d::KW, arg, letter)
# color # color
elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid)) elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid))
warn("Skipped grid arg $arg.") @warn("Skipped grid arg $arg.")
end end
end end
@ -834,7 +834,7 @@ function processMinorGridArg!(d::KW, arg, letter)
elseif handleColors!(d, arg, Symbol(letter, :foreground_color_minor_grid)) elseif handleColors!(d, arg, Symbol(letter, :foreground_color_minor_grid))
d[Symbol(letter, :minorgrid)] = true d[Symbol(letter, :minorgrid)] = true
else else
warn("Skipped grid arg $arg.") @warn("Skipped grid arg $arg.")
end end
end end
@ -867,7 +867,7 @@ function processFontArg!(d::KW, fontname::Symbol, arg)
elseif typeof(arg) <: Real elseif typeof(arg) <: Real
d[Symbol(fontname, :rotation)] = convert(Float64, arg) d[Symbol(fontname, :rotation)] = convert(Float64, arg)
else else
warn("Skipped font arg: $arg ($(typeof(arg)))") @warn("Skipped font arg: $arg ($(typeof(arg)))")
end end
end end
@ -1050,7 +1050,7 @@ function preprocessArgs!(d::KW)
# warnings for moved recipes # warnings for moved recipes
st = get(d, :seriestype, :path) st = get(d, :seriestype, :path)
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots) if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots)
warn("seriestype $st has been moved to StatPlots. To use: \`Pkg.add(\"StatPlots\"); using StatPlots\`") @warn("seriestype $st has been moved to StatPlots. To use: \`Pkg.add(\"StatPlots\"); using StatPlots\`")
end end
return return
@ -1070,7 +1070,7 @@ function extractGroupArgs(v::AVec, args...; legendEntry = string)
groupLabels = sort(collect(unique(v))) groupLabels = sort(collect(unique(v)))
n = length(groupLabels) n = length(groupLabels)
if n > 100 if n > 100
warn("You created n=$n groups... Is that intended?") @warn("You created n=$n groups... Is that intended?")
end end
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels] groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
GroupBy(map(legendEntry, groupLabels), groupIds) GroupBy(map(legendEntry, groupLabels), groupIds)
@ -1142,7 +1142,7 @@ function warnOnUnsupported_args(pkg::AbstractBackend, d::KW)
if !isempty(_to_warn) if !isempty(_to_warn)
for k in sort(collect(_to_warn)) for k in sort(collect(_to_warn))
push!(already_warned, k) push!(already_warned, k)
warn("Keyword argument $k not supported with $pkg. Choose from: $(supported_attrs(pkg))") @warn("Keyword argument $k not supported with $pkg. Choose from: $(supported_attrs(pkg))")
end end
end end
end end
@ -1153,13 +1153,13 @@ end
function warnOnUnsupported(pkg::AbstractBackend, d::KW) function warnOnUnsupported(pkg::AbstractBackend, d::KW)
if !is_seriestype_supported(pkg, d[:seriestype]) if !is_seriestype_supported(pkg, d[:seriestype])
warn("seriestype $(d[:seriestype]) is unsupported with $pkg. Choose from: $(supported_seriestypes(pkg))") @warn("seriestype $(d[:seriestype]) is unsupported with $pkg. Choose from: $(supported_seriestypes(pkg))")
end end
if !is_style_supported(pkg, d[:linestyle]) if !is_style_supported(pkg, d[:linestyle])
warn("linestyle $(d[:linestyle]) is unsupported with $pkg. Choose from: $(supported_styles(pkg))") @warn("linestyle $(d[:linestyle]) is unsupported with $pkg. Choose from: $(supported_styles(pkg))")
end end
if !is_marker_supported(pkg, d[:markershape]) if !is_marker_supported(pkg, d[:markershape])
warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supported_markers(pkg))") @warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supported_markers(pkg))")
end end
end end
@ -1168,7 +1168,7 @@ function warnOnUnsupported_scales(pkg::AbstractBackend, d::KW)
if haskey(d, k) if haskey(d, k)
v = d[k] v = d[k]
if !is_scale_supported(pkg, v) if !is_scale_supported(pkg, v)
warn("scale $v is unsupported with $pkg. Choose from: $(supported_scales(pkg))") @warn("scale $v is unsupported with $pkg. Choose from: $(supported_scales(pkg))")
end end
end end
end end

View File

@ -80,7 +80,7 @@ function process_axis_arg!(d::KW, arg, letter = "")
d[Symbol(letter,:formatter)] = arg d[Symbol(letter,:formatter)] = arg
elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_axis)) elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_axis))
warn("Skipped $(letter)axis arg $arg") @warn("Skipped $(letter)axis arg $arg")
end end
end end

View File

@ -6,6 +6,8 @@ const _backendType = Dict{Symbol, DataType}(:none => NoBackend)
const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none) const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none)
const _backends = Symbol[] const _backends = Symbol[]
const _initialized_backends = Set{Symbol}() const _initialized_backends = Set{Symbol}()
const _default_backends = (:none, :gr, :plotly)
const _backendPackage = Dict{Symbol, Symbol}()
"Returns a list of supported backends" "Returns a list of supported backends"
backends() = _backends backends() = _backends
@ -13,9 +15,12 @@ backends() = _backends
"Returns the name of the current backend" "Returns the name of the current backend"
backend_name() = CURRENT_BACKEND.sym backend_name() = CURRENT_BACKEND.sym
_backend_instance(sym::Symbol) = haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym") _backend_instance(sym::Symbol) = haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym")
backend_package(pkg::Symbol) = pkg in _default_backends ? :Plots : Symbol("Plots", _backendPackage[pkg])
backend_package_name(sym::Symbol) = sym in _default_backends ? :Plots : _backendPackage[sym]
macro init_backend(s) macro init_backend(s)
str = lowercase(string(s)) package_str = string(s)
str = lowercase(package_str)
sym = Symbol(str) sym = Symbol(str)
T = Symbol(string(s) * "Backend") T = Symbol(string(s) * "Backend")
esc(quote esc(quote
@ -23,14 +28,16 @@ macro init_backend(s)
export $sym export $sym
$sym(; kw...) = (default(; kw...); backend(Symbol($str))) $sym(; kw...) = (default(; kw...); backend(Symbol($str)))
backend_name(::$T) = Symbol($str) backend_name(::$T) = Symbol($str)
backend_package_name(pkg::$T) = backend_package_name(Symbol($str))
push!(_backends, Symbol($str)) push!(_backends, Symbol($str))
_backendType[Symbol($str)] = $T _backendType[Symbol($str)] = $T
_backendSymbol[$T] = Symbol($str) _backendSymbol[$T] = Symbol($str)
include("backends/" * $str * ".jl") _backendPackage[Symbol($str)] = Symbol($package_str)
# include("backends/" * $str * ".jl")
end) end)
end end
include("backends/web.jl") # include("backends/web.jl")
# include("backends/supported.jl") # include("backends/supported.jl")
# --------------------------------------------------------- # ---------------------------------------------------------
@ -40,7 +47,6 @@ function add_backend(pkg::Symbol)
println(add_backend_string(_backend_instance(pkg))) println(add_backend_string(_backend_instance(pkg)))
println() println()
end end
add_backend_string(b::AbstractBackend) = warn("No custom install defined for $(backend_name(b))")
# don't do anything as a default # don't do anything as a default
_create_backend_figure(plt::Plot) = nothing _create_backend_figure(plt::Plot) = nothing
@ -135,30 +141,30 @@ CurrentBackend(sym::Symbol) = CurrentBackend(sym, _backend_instance(sym))
function pickDefaultBackend() function pickDefaultBackend()
env_default = get(ENV, "PLOTS_DEFAULT_BACKEND", "") env_default = get(ENV, "PLOTS_DEFAULT_BACKEND", "")
if env_default != "" if env_default != ""
if env_default in keys(Pkg.installed())
sym = Symbol(lowercase(env_default)) sym = Symbol(lowercase(env_default))
if haskey(_backendType, sym) if sym in _backends
if sym in _initialized_backends
return backend(sym) return backend(sym)
else else
warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not a valid backend package. Choose from:\n\t", @warn("You have set `PLOTS_DEFAULT_BACKEND=$env_default` but `$(backend_package_name(sym))` is not loaded.")
join(sort(_backends), "\n\t"))
end end
else else
warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not installed.") @warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not a valid backend package. Choose from:\n\t",
join(sort(_backends), "\n\t"))
end end
end end
# the ordering/inclusion of this package list is my semi-arbitrary guess at # the ordering/inclusion of this package list is my semi-arbitrary guess at
# which one someone will want to use if they have the package installed...accounting for # which one someone will want to use if they have the package installed...accounting for
# features, speed, and robustness # features, speed, and robustness
for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize") # for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize")
if pkgstr in keys(Pkg.installed()) # if pkgstr in keys(Pkg.installed())
return backend(Symbol(lowercase(pkgstr))) # return backend(Symbol(lowercase(pkgstr)))
end # end
end # end
# the default if nothing else is installed # the default if nothing else is installed
backend(:plotly) backend(:gr)
end end
@ -174,24 +180,6 @@ function backend()
pickDefaultBackend() pickDefaultBackend()
end end
sym = CURRENT_BACKEND.sym
if !(sym in _initialized_backends)
# # initialize
# println("[Plots.jl] Initializing backend: ", sym)
inst = _backend_instance(sym)
try
_initialize_backend(inst)
catch err
warn("Couldn't initialize $sym. (might need to install it?)")
add_backend(sym)
rethrow(err)
end
push!(_initialized_backends, sym)
end
CURRENT_BACKEND.pkg CURRENT_BACKEND.pkg
end end
@ -199,16 +187,29 @@ end
Set the plot backend. Set the plot backend.
""" """
function backend(pkg::AbstractBackend) function backend(pkg::AbstractBackend)
sym = backend_name(pkg)
if sym in _initialized_backends
CURRENT_BACKEND.sym = backend_name(pkg) CURRENT_BACKEND.sym = backend_name(pkg)
warn_on_deprecated_backend(CURRENT_BACKEND.sym)
CURRENT_BACKEND.pkg = pkg CURRENT_BACKEND.pkg = pkg
else
# try
_initialize_backend(pkg)
push!(_initialized_backends, sym)
CURRENT_BACKEND.sym = backend_name(pkg)
CURRENT_BACKEND.pkg = pkg
# catch
# add_backend(sym)
# end
end
backend() backend()
end end
function backend(modname::Symbol) function backend(sym::Symbol)
warn_on_deprecated_backend(modname) if sym in _backends
CURRENT_BACKEND.sym = modname backend(_backend_instance(sym))
CURRENT_BACKEND.pkg = _backend_instance(modname) else
@warn("`:$sym` is not a supported backend.")
end
backend() backend()
end end
@ -216,7 +217,7 @@ const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse]
function warn_on_deprecated_backend(bsym::Symbol) function warn_on_deprecated_backend(bsym::Symbol)
if bsym in _deprecated_backends if bsym in _deprecated_backends
warn("Backend $bsym has been deprecated. It may not work as originally intended.") @warn("Backend $bsym has been deprecated. It may not work as originally intended.")
end end
end end
@ -308,3 +309,109 @@ end
# is_subplot_supported(::AbstractBackend) = false # is_subplot_supported(::AbstractBackend) = false
# is_subplot_supported() = is_subplot_supported(backend()) # is_subplot_supported() = is_subplot_supported(backend())
################################################################################
# initialize the backends
function _initialize_backend(pkg::AbstractBackend)
sym = backend_package_name(pkg)
@eval Main begin
import $sym
export $sym
end
end
function add_backend_string(pkg::AbstractBackend)
sym = backend_package_name(pkg)
"""
using Pkg
Pkg.add("$sym")
"""
end
# ------------------------------------------------------------------------------
# glvisualize
function _initialize_backend(::GLVisualizeBackend; kw...)
@eval Main begin
import GLVisualize, GeometryTypes, Reactive, GLAbstraction, GLWindow, Contour
import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle, Point, Vec
import FileIO, Images
export GLVisualize
import Reactive: Signal
import GLAbstraction: Style
import GLVisualize: visualize
import Plots.GL
import UnicodeFun
end
end
# ------------------------------------------------------------------------------
# hdf5
function _initialize_backend(::HDF5Backend)
@eval Main begin
import HDF5
export HDF5
end
end
# ------------------------------------------------------------------------------
# PGFPLOTS
function add_backend_string(::PGFPlotsBackend)
"""
using Pkg
Pkg.add("PGFPlots")
Pkg.build("PGFPlots")
"""
end
# ------------------------------------------------------------------------------
# plotlyjs
function add_backend_string(::PlotlyJSBackend)
"""
using Pkg
Pkg.add("PlotlyJS")
Pkg.add("Rsvg")
import Blink
Blink.AtomShell.install()
"""
end
# ------------------------------------------------------------------------------
# pyplot
function _initialize_backend(::PyPlotBackend)
@eval Main begin
import PyPlot, PyCall
import LaTeXStrings: latexstring
export PyPlot
# we don't want every command to update the figure
PyPlot.ioff()
end
end
function add_backend_string(::PyPlotBackend)
"""
using Pkg
Pkg.add("PyPlot")
withenv("PYTHON" => "") do
Pkg.build("PyPlot")
end
"""
end
# ------------------------------------------------------------------------------
# unicodeplots
function add_backend_string(::UnicodePlotsBackend)
"""
using Pkg
Pkg.add("UnicodePlots")
Pkg.build("UnicodePlots")
"""
end

View File

@ -9,10 +9,6 @@ TODO
* fix units in all visuals (e.g dotted lines, marker scale, surfaces) * fix units in all visuals (e.g dotted lines, marker scale, surfaces)
=# =#
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "glvisualize.jl"))
end
const _glvisualize_attr = merge_with_base_supported([ const _glvisualize_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :background_color_inside, :background_color_outside, :background_color_legend, :background_color_inside, :background_color_outside,
@ -61,36 +57,11 @@ const _glvisualize_style = [:auto, :solid, :dash, :dot, :dashdot]
const _glvisualize_marker = _allMarkers const _glvisualize_marker = _allMarkers
const _glvisualize_scale = [:identity, :ln, :log2, :log10] const _glvisualize_scale = [:identity, :ln, :log2, :log10]
slice_arg(img::Matrix{C}, idx::Int) where {C<:Colorant} = img
is_marker_supported(::GLVisualizeBackend, shape::GLVisualize.AllPrimitives) = true
# -------------------------------------------------------------------------------------- is_marker_supported(::GLVisualizeBackend, shape::Union{Vector{Matrix{C}}, Matrix{C}}) where {C<:Colorant} = true
is_marker_supported(::GLVisualizeBackend, shape::Shape) = true
function _initialize_backend(::GLVisualizeBackend; kw...) GL = Plots
@eval begin
import GLVisualize, GeometryTypes, Reactive, GLAbstraction, GLWindow, Contour
import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle, Point, Vec
import FileIO, Images
export GLVisualize
import Reactive: Signal
import GLAbstraction: Style
import GLVisualize: visualize
import Plots.GL
import UnicodeFun
Plots.slice_arg(img::Matrix{C}, idx::Int) where {C<:Colorant} = img
is_marker_supported(::GLVisualizeBackend, shape::GLVisualize.AllPrimitives) = true
is_marker_supported(::GLVisualizeBackend, shape::Union{Vector{Matrix{C}}, Matrix{C}}) where {C<:Colorant} = true
is_marker_supported(::GLVisualizeBackend, shape::Shape) = true
GL = Plots
end
end
function add_backend_string(b::GLVisualizeBackend)
"""
if !Plots.is_installed("GLVisualize")
Pkg.add("GLVisualize")
end
"""
end
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -1329,7 +1300,7 @@ function gl_poly(points, kw_args)
if !isempty(GeometryTypes.faces(mesh)) # check if polygonation has any faces if !isempty(GeometryTypes.faces(mesh)) # check if polygonation has any faces
push!(result, GLVisualize.visualize(mesh, Style(:default), kw_args)) push!(result, GLVisualize.visualize(mesh, Style(:default), kw_args))
else else
warn("Couldn't draw the polygon: $points") @warn("Couldn't draw the polygon: $points")
end end
end end
result result

View File

@ -3,10 +3,6 @@
# significant contributions by @jheinen # significant contributions by @jheinen
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "gr.jl"))
end
const _gr_attr = merge_with_base_supported([ const _gr_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :background_color_inside, :background_color_outside, :background_color_legend, :background_color_inside, :background_color_outside,
@ -65,12 +61,8 @@ function add_backend_string(::GRBackend)
""" """
end end
function _initialize_backend(::GRBackend; kw...) import GR
@eval begin export GR
import GR
export GR
end
end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
@ -624,7 +616,7 @@ end
function _update_min_padding!(sp::Subplot{GRBackend}) function _update_min_padding!(sp::Subplot{GRBackend})
dpi = sp.plt[:thickness_scaling] dpi = sp.plt[:thickness_scaling]
if !haskey(ENV, "GKSwstype") if !haskey(ENV, "GKSwstype")
if isijulia() || (isdefined(Main, :Juno) && Juno.isactive()) if isijulia()
ENV["GKSwstype"] = "svg" ENV["GKSwstype"] = "svg"
end end
end end

View File

@ -28,10 +28,6 @@ Read from .hdf5 file using:
- Should be reliable for archival purposes. - Should be reliable for archival purposes.
==# ==#
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "hdf5.jl"))
end
import FixedPointNumbers: N0f8 #In core Julia import FixedPointNumbers: N0f8 #In core Julia
#Dispatch types: #Dispatch types:
@ -108,43 +104,7 @@ const _hdf5_marker = vcat(_allMarkers, :pixel)
const _hdf5_scale = [:identity, :ln, :log2, :log10] const _hdf5_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::HDF5Backend, shape::Shape) = true is_marker_supported(::HDF5Backend, shape::Shape) = true
function add_backend_string(::HDF5Backend) if length(HDF5PLOT_MAP_TELEM2STR) < 1
"""
if !Plots.is_installed("HDF5")
Pkg.add("HDF5")
end
"""
end
#==Helper functions
===============================================================================#
_hdf5_plotelempath(subpath::String) = "$_hdf5_plotroot/$subpath"
_hdf5_datapath(subpath::String) = "$_hdf5_dataroot/$subpath"
_hdf5_map_str2telem(k::String) = HDF5PLOT_MAP_STR2TELEM[k]
_hdf5_map_str2telem(v::Vector) = HDF5PLOT_MAP_STR2TELEM[v[1]]
function _hdf5_merge!(dest::Dict, src::Dict)
for (k, v) in src
if isa(v, Axis)
_hdf5_merge!(dest[k].d, v.d)
else
dest[k] = v
end
end
return
end
#==
===============================================================================#
function _initialize_backend(::HDF5Backend)
@eval begin
import HDF5
export HDF5
if length(HDF5PLOT_MAP_TELEM2STR) < 1
#Possible element types of high-level data types: #Possible element types of high-level data types:
telem2str = Dict{String, Type}( telem2str = Dict{String, Type}(
"NATIVE" => HDF5PlotNative, "NATIVE" => HDF5PlotNative,
@ -173,11 +133,32 @@ function _initialize_backend(::HDF5Backend)
) )
merge!(HDF5PLOT_MAP_STR2TELEM, telem2str) merge!(HDF5PLOT_MAP_STR2TELEM, telem2str)
merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM)) merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM))
end
end
end end
# ---------------------------------------------------------------------------
#==Helper functions
===============================================================================#
_hdf5_plotelempath(subpath::String) = "$_hdf5_plotroot/$subpath"
_hdf5_datapath(subpath::String) = "$_hdf5_dataroot/$subpath"
_hdf5_map_str2telem(k::String) = HDF5PLOT_MAP_STR2TELEM[k]
_hdf5_map_str2telem(v::Vector) = HDF5PLOT_MAP_STR2TELEM[v[1]]
function _hdf5_merge!(dest::Dict, src::Dict)
for (k, v) in src
if isa(v, Axis)
_hdf5_merge!(dest[k].d, v.d)
else
dest[k] = v
end
end
return
end
#==
===============================================================================#
# Create the window/figure for this backend. # Create the window/figure for this backend.
function _create_backend_figure(plt::Plot{HDF5Backend}) function _create_backend_figure(plt::Plot{HDF5Backend})
@ -244,7 +225,7 @@ end
function _display(plt::Plot{HDF5Backend}) function _display(plt::Plot{HDF5Backend})
msg = "HDF5 interface does not support `display()` function." msg = "HDF5 interface does not support `display()` function."
msg *= "\nUse `Plots.hdf5plot_write(::String)` method to write to .HDF5 \"plot\" file instead." msg *= "\nUse `Plots.hdf5plot_write(::String)` method to write to .HDF5 \"plot\" file instead."
warn(msg) @warn(msg)
return return
end end
@ -312,7 +293,7 @@ end
#= #=
function _hdf5plot_gwrite(grp, k::String, v::Array{Any}) function _hdf5plot_gwrite(grp, k::String, v::Array{Any})
# @show grp, k # @show grp, k
warn("Cannot write Array: $k=$v") @warn("Cannot write Array: $k=$v")
end end
=# =#
function _hdf5plot_gwrite(grp, k::String, v::Nothing) function _hdf5plot_gwrite(grp, k::String, v::Nothing)
@ -342,7 +323,7 @@ function _hdf5plot_gwrite(grp, k::String, v::Tuple)
#NOTE: _hdf5plot_overwritetype overwrites "Array" type with "Tuple". #NOTE: _hdf5plot_overwritetype overwrites "Array" type with "Tuple".
end end
function _hdf5plot_gwrite(grp, k::String, d::Dict) function _hdf5plot_gwrite(grp, k::String, d::Dict)
# warn("Cannot write dict: $k=$d") # @warn("Cannot write dict: $k=$d")
end end
function _hdf5plot_gwrite(grp, k::String, v::AbstractRange) function _hdf5plot_gwrite(grp, k::String, v::AbstractRange)
_hdf5plot_gwrite(grp, k, collect(v)) #For now _hdf5plot_gwrite(grp, k, collect(v)) #For now
@ -605,7 +586,7 @@ function _hdf5plot_read(grp, d::Dict)
catch e catch e
@show e @show e
@show grp @show grp
warn("Could not read field $k") @warn("Could not read field $k")
end end
end end
return return

View File

@ -13,10 +13,6 @@ Add in functionality to Plots.jl:
:aspect_ratio, :aspect_ratio,
=# =#
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "inspectdr.jl"))
end
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
#TODO: remove features #TODO: remove features
const _inspectdr_attr = merge_with_base_supported([ const _inspectdr_attr = merge_with_base_supported([
@ -152,38 +148,24 @@ end
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
function add_backend_string(::InspectDRBackend) #Glyph used when plotting "Shape"s:
""" INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
if !Plots.is_installed("InspectDR")
Pkg.add("InspectDR")
end
"""
end
function _initialize_backend(::InspectDRBackend; kw...)
@eval begin
import InspectDR
export InspectDR
#Glyph used when plotting "Shape"s:
INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y 2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y
) )
mutable struct InspecDRPlotRef mutable struct InspecDRPlotRef
mplot::Union{Nothing, InspectDR.Multiplot} mplot::Union{Nothing, InspectDR.Multiplot}
gui::Union{Nothing, InspectDR.GtkPlot} gui::Union{Nothing, InspectDR.GtkPlot}
end
_inspectdr_getmplot(::Any) = nothing
_inspectdr_getmplot(r::InspecDRPlotRef) = r.mplot
_inspectdr_getgui(::Any) = nothing
_inspectdr_getgui(gplot::InspectDR.GtkPlot) = (gplot.destroyed ? nothing : gplot)
_inspectdr_getgui(r::InspecDRPlotRef) = _inspectdr_getgui(r.gui)
end
end end
_inspectdr_getmplot(::Any) = nothing
_inspectdr_getmplot(r::InspecDRPlotRef) = r.mplot
_inspectdr_getgui(::Any) = nothing
_inspectdr_getgui(gplot::InspectDR.GtkPlot) = (gplot.destroyed ? nothing : gplot)
_inspectdr_getgui(r::InspecDRPlotRef) = _inspectdr_getgui(r.gui)
push!(_initialized_backends, :inspectdr)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Create the window/figure for this backend. # Create the window/figure for this backend.

View File

@ -2,10 +2,6 @@
# significant contributions by: @pkofod # significant contributions by: @pkofod
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "pgfplots.jl"))
end
const _pgfplots_attr = merge_with_base_supported([ const _pgfplots_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :background_color_legend,
@ -47,23 +43,6 @@ const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :d
const _pgfplots_scale = [:identity, :ln, :log2, :log10] const _pgfplots_scale = [:identity, :ln, :log2, :log10]
# --------------------------------------------------------------------------------------
function add_backend_string(::PGFPlotsBackend)
"""
Pkg.add("PGFPlots")
Pkg.build("PGFPlots")
"""
end
function _initialize_backend(::PGFPlotsBackend; kw...)
@eval begin
import PGFPlots
export PGFPlots
end
end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
const _pgfplots_linestyles = KW( const _pgfplots_linestyles = KW(
@ -124,7 +103,7 @@ function pgf_framestyle(style::Symbol)
return style return style
else else
default_style = get(_pgf_framestyle_defaults, style, :axes) default_style = get(_pgf_framestyle_defaults, style, :axes)
warn("Framestyle :$style is not (yet) supported by the PGFPlots backend. :$default_style was cosen instead.") @warn("Framestyle :$style is not (yet) supported by the PGFPlots backend. :$default_style was cosen instead.")
default_style default_style
end end
end end

View File

@ -1,10 +1,6 @@
# https://plot.ly/javascript/getting-started # https://plot.ly/javascript/getting-started
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl"))
end
const _plotly_attr = merge_with_base_supported([ const _plotly_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :background_color_inside, :background_color_outside, :background_color_legend, :background_color_inside, :background_color_outside,
@ -68,7 +64,7 @@ function _plotly_framestyle(style::Symbol)
return style return style
else else
default_style = get(_plotly_framestyle_defaults, style, :axes) default_style = get(_plotly_framestyle_defaults, style, :axes)
warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.") @warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.")
default_style default_style
end end
end end
@ -76,22 +72,14 @@ end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
function add_backend_string(::PlotlyBackend)
"""
Pkg.build("Plots")
"""
end
const _plotly_js_path = joinpath(dirname(@__FILE__), "..", "..", "deps", "plotly-latest.min.js") const _plotly_js_path = joinpath(dirname(@__FILE__), "..", "..", "deps", "plotly-latest.min.js")
const _plotly_js_path_remote = "https://cdn.plot.ly/plotly-latest.min.js" const _plotly_js_path_remote = "https://cdn.plot.ly/plotly-latest.min.js"
function _initialize_backend(::PlotlyBackend; kw...) _js_code = open(read, _plotly_js_path, "r")
@eval begin
_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 # borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2
_js_script = """ _js_script = """
<script type='text/javascript'> <script type='text/javascript'>
define('plotly', function(require, exports, module) { define('plotly', function(require, exports, module) {
$(_js_code) $(_js_code)
@ -100,22 +88,21 @@ function _initialize_backend(::PlotlyBackend; kw...)
window.Plotly = Plotly; window.Plotly = Plotly;
}); });
</script> </script>
""" """
# if we're in IJulia call setupnotebook to load js and css # if we're in IJulia call setupnotebook to load js and css
if isijulia() if isijulia()
display("text/html", _js_script) display("text/html", _js_script)
end
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
end
# TODO: other initialization
end end
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
using UUIDs
push!(_initialized_backends, :plotly)
# ---------------------------------------------------------------- # ----------------------------------------------------------------
@ -631,7 +618,7 @@ function plotly_series(plt::Plot, series::Series)
d_out[:hoverinfo] = "label+percent+name" d_out[:hoverinfo] = "label+percent+name"
else else
warn("Plotly: seriestype $st isn't supported.") @warn("Plotly: seriestype $st isn't supported.")
return KW() return KW()
end end
@ -744,7 +731,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
d_out[:fill] = "tonexty" d_out[:fill] = "tonexty"
d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i))) d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i)))
elseif !(series[:fillrange] in (false, nothing)) elseif !(series[:fillrange] in (false, nothing))
warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])") @warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])")
end end
d_out[:x], d_out[:y] = x[rng], y[rng] d_out[:x], d_out[:y] = x[rng], y[rng]
@ -906,7 +893,7 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing)
w, h = plt[:size] w, h = plt[:size]
style = "width:$(w)px;height:$(h)px;" style = "width:$(w)px;height:$(h)px;"
end end
uuid = Base.Random.uuid4() uuid = UUIDs.uuid4()
html = """ html = """
<div id=\"$(uuid)\" style=\"$(style)\"></div> <div id=\"$(uuid)\" style=\"$(style)\"></div>
<script> <script>

View File

@ -1,6 +1,3 @@
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotlyjs.jl"))
end
# https://github.com/spencerlyon2/PlotlyJS.jl # https://github.com/spencerlyon2/PlotlyJS.jl
@ -13,35 +10,6 @@ const _plotlyjs_scale = _plotly_scale
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
function add_backend_string(::PlotlyJSBackend)
"""
if !Plots.is_installed("PlotlyJS")
Pkg.add("PlotlyJS")
end
if !Plots.is_installed("Rsvg")
Pkg.add("Rsvg")
end
import Blink
Blink.AtomShell.install()
"""
end
function _initialize_backend(::PlotlyJSBackend; kw...)
@eval begin
import PlotlyJS
export PlotlyJS
end
# # override IJulia inline display
# if isijulia()
# IJulia.display_dict(plt::AbstractPlot{PlotlyJSBackend}) = IJulia.display_dict(plt.o)
# end
end
# ---------------------------------------------------------------------------
function _create_backend_figure(plt::Plot{PlotlyJSBackend}) function _create_backend_figure(plt::Plot{PlotlyJSBackend})
if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot) if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot)
PlotlyJS.SyncPlot(PlotlyJS.Plot(), current().o.view) PlotlyJS.SyncPlot(PlotlyJS.Plot(), current().o.view)

View File

@ -1,10 +1,6 @@
# https://github.com/stevengj/PyPlot.jl # https://github.com/stevengj/PyPlot.jl
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "pyplot.jl"))
end
const _pyplot_attr = merge_with_base_supported([ const _pyplot_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :background_color_inside, :background_color_outside, :background_color_legend, :background_color_inside, :background_color_outside,
@ -59,57 +55,31 @@ is_marker_supported(::PyPlotBackend, shape::Shape) = true
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
function add_backend_string(::PyPlotBackend) # problem: https://github.com/tbreloff/Plots.jl/issues/308
""" # solution: hack from @stevengj: https://github.com/stevengj/PyPlot.jl/pull/223#issuecomment-229747768
if !Plots.is_installed("PyPlot") otherdisplays = splice!(Base.Multimedia.displays, 2:length(Base.Multimedia.displays))
Pkg.add("PyPlot") append!(Base.Multimedia.displays, otherdisplays)
end pycolors = PyPlot.pyimport("matplotlib.colors")
withenv("PYTHON" => "") do pypath = PyPlot.pyimport("matplotlib.path")
Pkg.build("PyPlot") mplot3d = PyPlot.pyimport("mpl_toolkits.mplot3d")
end pypatches = PyPlot.pyimport("matplotlib.patches")
pyfont = PyPlot.pyimport("matplotlib.font_manager")
pyticker = PyPlot.pyimport("matplotlib.ticker")
pycmap = PyPlot.pyimport("matplotlib.cm")
pynp = PyPlot.pyimport("numpy")
pynp["seterr"](invalid="ignore")
pytransforms = PyPlot.pyimport("matplotlib.transforms")
pycollections = PyPlot.pyimport("matplotlib.collections")
pyart3d = PyPlot.art3D
# now restart julia! # "support" matplotlib v1.5
""" set_facecolor_sym = if PyPlot.version < v"2"
end @warn("You are using Matplotlib $(PyPlot.version), which is no longer officialy supported by the Plots community. To ensure smooth Plots.jl integration update your Matplotlib library to a version >= 2.0.0")
function _initialize_backend(::PyPlotBackend)
@eval begin
# problem: https://github.com/tbreloff/Plots.jl/issues/308
# solution: hack from @stevengj: https://github.com/stevengj/PyPlot.jl/pull/223#issuecomment-229747768
otherdisplays = splice!(Base.Multimedia.displays, 2:length(Base.Multimedia.displays))
import PyPlot, PyCall
import LaTeXStrings: latexstring
append!(Base.Multimedia.displays, otherdisplays)
export PyPlot
pycolors = PyPlot.pyimport("matplotlib.colors")
pypath = PyPlot.pyimport("matplotlib.path")
mplot3d = PyPlot.pyimport("mpl_toolkits.mplot3d")
pypatches = PyPlot.pyimport("matplotlib.patches")
pyfont = PyPlot.pyimport("matplotlib.font_manager")
pyticker = PyPlot.pyimport("matplotlib.ticker")
pycmap = PyPlot.pyimport("matplotlib.cm")
pynp = PyPlot.pyimport("numpy")
pynp["seterr"](invalid="ignore")
pytransforms = PyPlot.pyimport("matplotlib.transforms")
pycollections = PyPlot.pyimport("matplotlib.collections")
pyart3d = PyPlot.art3D
# "support" matplotlib v1.5
set_facecolor_sym = if PyPlot.version < v"2"
warn("You are using Matplotlib $(PyPlot.version), which is no longer officialy supported by the Plots community. To ensure smooth Plots.jl integration update your Matplotlib library to a version >= 2.0.0")
:set_axis_bgcolor :set_axis_bgcolor
else else
:set_facecolor :set_facecolor
end
# we don't want every command to update the figure
PyPlot.ioff()
end
end end
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# # convert colorant to 4-tuple RGBA # # convert colorant to 4-tuple RGBA
# py_color(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (red, green, blue, alpha)) # py_color(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (red, green, blue, alpha))
@ -160,7 +130,7 @@ function py_linestyle(seriestype::Symbol, linestyle::Symbol)
linestyle == :dash && return "--" linestyle == :dash && return "--"
linestyle == :dot && return ":" linestyle == :dot && return ":"
linestyle == :dashdot && return "-." linestyle == :dashdot && return "-."
warn("Unknown linestyle $linestyle") @warn("Unknown linestyle $linestyle")
return "-" return "-"
end end
@ -221,13 +191,13 @@ function py_marker(marker::Symbol)
marker == :vline && return "|" marker == :vline && return "|"
haskey(_shapes, marker) && return py_marker(_shapes[marker]) haskey(_shapes, marker) && return py_marker(_shapes[marker])
warn("Unknown marker $marker") @warn("Unknown marker $marker")
return "o" return "o"
end end
# py_marker(markers::AVec) = map(py_marker, markers) # py_marker(markers::AVec) = map(py_marker, markers)
function py_marker(markers::AVec) function py_marker(markers::AVec)
warn("Vectors of markers are currently unsupported in PyPlot: $markers") @warn("Vectors of markers are currently unsupported in PyPlot: $markers")
py_marker(markers[1]) py_marker(markers[1])
end end
@ -279,10 +249,12 @@ function labelfunc(scale::Symbol, backend::PyPlotBackend)
end end
end end
function py_mask_nans(z) @require PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" begin
function py_mask_nans(z)
# pynp["ma"][:masked_invalid](z))) # pynp["ma"][:masked_invalid](z)))
PyCall.pycall(pynp["ma"][:masked_invalid], Any, z) PyCall.pycall(pynp["ma"][:masked_invalid], Any, z)
# pynp["ma"][:masked_where](pynp["isnan"](z),z) # pynp["ma"][:masked_where](pynp["isnan"](z),z)
end
end end
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -542,7 +514,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
a = series[:arrow] a = series[:arrow]
if a != nothing && !is3d(st) # TODO: handle 3d later if a != nothing && !is3d(st) # TODO: handle 3d later
if typeof(a) != Arrow if typeof(a) != Arrow
warn("Unexpected type for arrow: $(typeof(a))") @warn("Unexpected type for arrow: $(typeof(a))")
else else
arrowprops = KW( arrowprops = KW(
:arrowstyle => "simple,head_length=$(a.headlength),head_width=$(a.headwidth)", :arrowstyle => "simple,head_length=$(a.headlength),head_width=$(a.headwidth)",
@ -912,7 +884,7 @@ end
function py_set_scale(ax, axis::Axis) function py_set_scale(ax, axis::Axis)
scale = axis[:scale] scale = axis[:scale]
letter = axis[:letter] letter = axis[:letter]
scale in supported_scales() || return warn("Unhandled scale value in pyplot: $scale") scale in supported_scales() || return @warn("Unhandled scale value in pyplot: $scale")
func = ax[Symbol("set_", letter, "scale")] func = ax[Symbol("set_", letter, "scale")]
kw = KW() kw = KW()
arg = if scale == :identity arg = if scale == :identity

View File

@ -3,14 +3,9 @@
# [ADD BACKEND WEBSITE] # [ADD BACKEND WEBSITE]
function _initialize_backend(::[PkgName]Backend; kw...) import [PkgName]
@eval begin export [PkgName]
import [PkgName] push!(_initialized_backends, [pgkname]::Symbol)
export [PkgName]
# todo: other initialization that needs to be eval-ed
end
# todo: other initialization
end
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@ -1,10 +1,6 @@
# https://github.com/Evizero/UnicodePlots.jl # https://github.com/Evizero/UnicodePlots.jl
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "unicodeplots.jl"))
end
const _unicodeplots_attr = merge_with_base_supported([ const _unicodeplots_attr = merge_with_base_supported([
:label, :label,
:legend, :legend,
@ -33,22 +29,6 @@ warnOnUnsupported_args(::UnicodePlotsBackend, d::KW) = nothing
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
function add_backend_string(::UnicodePlotsBackend)
"""
Pkg.add("UnicodePlots")
Pkg.build("UnicodePlots")
"""
end
function _initialize_backend(::UnicodePlotsBackend; kw...)
@eval begin
import UnicodePlots
export UnicodePlots
end
end
# -------------------------------
const _canvas_type = Ref(:auto) const _canvas_type = Ref(:auto)
function _canvas_map() function _canvas_map()

View File

@ -2,9 +2,6 @@
# NOTE: backend should implement `html_body` and `html_head` # NOTE: backend should implement `html_body` and `html_head`
# CREDIT: parts of this implementation were inspired by @joshday's PlotlyLocal.jl # CREDIT: parts of this implementation were inspired by @joshday's PlotlyLocal.jl
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" begin
Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "web.jl"))
end
function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr, :window_title, "Plots.jl")) function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr, :window_title, "Plots.jl"))
""" """

View File

@ -7,7 +7,7 @@ nanpush!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); push!(a, b))
nanappend!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); append!(a, b)) nanappend!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); append!(a, b))
nanpush!(a::AbstractVector{P3}, b) = (push!(a, P3(NaN,NaN,NaN)); push!(a, b)) nanpush!(a::AbstractVector{P3}, b) = (push!(a, P3(NaN,NaN,NaN)); push!(a, b))
nanappend!(a::AbstractVector{P3}, b) = (push!(a, P3(NaN,NaN,NaN)); append!(a, b)) nanappend!(a::AbstractVector{P3}, b) = (push!(a, P3(NaN,NaN,NaN)); append!(a, b))
compute_angle(v::P2) = (angle = atan2(v[2], v[1]); angle < 0 ? 2π - angle : angle) compute_angle(v::P2) = (angle = atan(v[2], v[1]); angle < 0 ? 2π - angle : angle)
# ------------------------------------------------------------- # -------------------------------------------------------------
@ -297,7 +297,7 @@ function font(args...)
elseif typeof(arg) <: Real elseif typeof(arg) <: Real
rotation = convert(Float64, arg) rotation = convert(Float64, arg)
else else
warn("Unused font arg: $arg ($(typeof(arg)))") @warn("Unused font arg: $arg ($(typeof(arg)))")
end end
end end
@ -396,7 +396,7 @@ function stroke(args...; alpha = nothing)
elseif allReals(arg) elseif allReals(arg)
width = arg width = arg
else else
warn("Unused stroke arg: $arg ($(typeof(arg)))") @warn("Unused stroke arg: $arg ($(typeof(arg)))")
end end
end end
@ -429,7 +429,7 @@ function brush(args...; alpha = nothing)
elseif allReals(arg) elseif allReals(arg)
size = arg size = arg
else else
warn("Unused brush arg: $arg ($(typeof(arg)))") @warn("Unused brush arg: $arg ($(typeof(arg)))")
end end
end end
@ -460,7 +460,7 @@ function series_annotations(strs::AbstractVector, args...)
elseif is_2tuple(arg) elseif is_2tuple(arg)
scalefactor = arg scalefactor = arg
else else
warn("Unused SeriesAnnotations arg: $arg ($(typeof(arg)))") @warn("Unused SeriesAnnotations arg: $arg ($(typeof(arg)))")
end end
end end
# if scalefactor != 1 # if scalefactor != 1
@ -523,9 +523,12 @@ mutable struct EachAnn
x x
y y
end end
Base.start(ea::EachAnn) = 1
Base.done(ea::EachAnn, i) = ea.anns == nothing || isempty(ea.anns.strs) || i > length(ea.y) function Base.iterate(ea::EachAnn, i = 1)
function Base.next(ea::EachAnn, i) if ea.anns == nothing || isempty(ea.anns.strs) || i > length(ea.y)
return nothing
end
tmp = _cycle(ea.anns.strs,i) tmp = _cycle(ea.anns.strs,i)
str,fnt = if isa(tmp, PlotText) str,fnt = if isa(tmp, PlotText)
tmp.str, tmp.font tmp.str, tmp.font
@ -701,7 +704,7 @@ function arrow(args...)
elseif T <: Tuple && length(arg) == 2 elseif T <: Tuple && length(arg) == 2
headlength, headwidth = Float64(arg[1]), Float64(arg[2]) headlength, headwidth = Float64(arg[1]), Float64(arg[2])
else else
warn("Skipped arrow arg $arg") @warn("Skipped arrow arg $arg")
end end
end end
Arrow(style, side, headlength, headwidth) Arrow(style, side, headlength, headwidth)

View File

@ -197,7 +197,7 @@ function getGadflyMarkerTheme(d::KW, attr::KW)
ms = d[:markersize] ms = d[:markersize]
ms = if typeof(ms) <: AVec ms = if typeof(ms) <: AVec
warn("Gadfly doesn't support variable marker sizes... using the average: $(mean(ms))") @warn("Gadfly doesn't support variable marker sizes... using the average: $(mean(ms))")
mean(ms) * Gadfly.px mean(ms) * Gadfly.px
else else
ms * Gadfly.px ms * Gadfly.px

View File

@ -150,7 +150,7 @@ function updateLimsAndTicks(plt::Plot{QwtBackend}, d::KW, isx::Bool)
end end
w[:setAxisScale](axisid, float(minimum(ticks)), float(maximum(ticks)), float(step(ticks))) w[:setAxisScale](axisid, float(minimum(ticks)), float(maximum(ticks)), float(step(ticks)))
elseif !(ticks in (nothing, :none, :auto)) elseif !(ticks in (nothing, :none, :auto))
warn("Only Range types are supported for Qwt xticks/yticks. typeof(ticks)=$(typeof(ticks))") @warn("Only Range types are supported for Qwt xticks/yticks. typeof(ticks)=$(typeof(ticks))")
end end
# change the scale # change the scale
@ -161,7 +161,7 @@ function updateLimsAndTicks(plt::Plot{QwtBackend}, d::KW, isx::Bool)
# scaletype == :log && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLogScaleEngine(e)) # scaletype == :log && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLogScaleEngine(e))
# scaletype == :log2 && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLogScaleEngine(2)) # scaletype == :log2 && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLogScaleEngine(2))
scaletype == :log10 && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLog10ScaleEngine()) scaletype == :log10 && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLog10ScaleEngine())
scaletype in supported_scales() || warn("Unsupported scale type: ", scaletype) scaletype in supported_scales() || @warn("Unsupported scale type: ", scaletype)
end end
end end

70
src/init.jl Normal file
View File

@ -0,0 +1,70 @@
function __init__()
include(joinpath(@__DIR__, "backends", "plotly.jl"))
include(joinpath(@__DIR__, "backends", "gr.jl"))
include(joinpath(@__DIR__, "backends", "web.jl"))
@require GLVisualize = "4086de5b-f4b6-55f3-abb0-b8c73827585f" include(joinpath(@__DIR__, "backends", "gr.jl"))
@require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" include(joinpath(@__DIR__, "backends", "hdf5.jl"))
@require InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d" include(joinpath(@__DIR__, "backends", "inspectdr.jl"))
@require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" include(joinpath(@__DIR__, "backends", "pgfplots.jl"))
@require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" include(joinpath(@__DIR__, "backends", "plotlyjs.jl"))
@require PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" include(joinpath(@__DIR__, "backends", "pyplot.jl"))
@require UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" include(joinpath(@__DIR__, "backends", "unicodeplots.jl"))
# ---------------------------------------------------------
# IJulia
# ---------------------------------------------------------
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
if IJulia.inited
"""
Add extra jupyter mimetypes to display_dict based on the plot backed.
The default is nothing, except for plotly based backends, where it
adds data for `application/vnd.plotly.v1+json` that is used in
frontends like jupyterlab and nteract.
"""
_extra_mime_info!(plt::Plot, out::Dict) = out
function _extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict)
out["application/vnd.plotly.v1+json"] = JSON.lower(plt.o)
out
end
function _extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict)
out["application/vnd.plotly.v1+json"] = Dict(
:data => plotly_series(plt),
:layout => plotly_layout(plt)
)
out
end
function IJulia.display_dict(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
out = Dict()
if output_type == :txt
mime = "text/plain"
out[mime] = sprint(show, MIME(mime), plt)
elseif output_type == :png
mime = "image/png"
out[mime] = base64encode(show, MIME(mime), plt)
elseif output_type == :svg
mime = "image/svg+xml"
out[mime] = sprint(show, MIME(mime), plt)
elseif output_type == :html
mime = "text/html"
out[mime] = sprint(show, MIME(mime), plt)
else
error("Unsupported output type $output_type")
end
_extra_mime_info!(plt, out)
out
end
ENV["MPLBACKEND"] = "Agg"
end
end
end

View File

@ -5,8 +5,8 @@ to_pixels(m::AbsoluteLength) = m.value / 0.254
const _cbar_width = 5mm const _cbar_width = 5mm
Base.broadcast(::typeof(Base.:.*), m::Measure, n::Number) = m * n #Base.broadcast(::typeof(Base.:.*), m::Measure, n::Number) = m * n
Base.broadcast(::typeof(Base.:.*), m::Number, n::Measure) = m * n #Base.broadcast(::typeof(Base.:.*), m::Number, n::Measure) = m * n
Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a) Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a) Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a)
Base.zero(::Type{typeof(mm)}) = 0mm Base.zero(::Type{typeof(mm)}) = 0mm
@ -147,7 +147,7 @@ function bbox(x, y, w, h, oarg1::Symbol, originargs::Symbol...)
elseif oarg in (:top, :bottom, :vcenter) elseif oarg in (:top, :bottom, :vcenter)
origver = oarg origver = oarg
else else
warn("Unused origin arg in bbox construction: $oarg") @warn("Unused origin arg in bbox construction: $oarg")
end end
end end
bbox(x, y, w, h; h_anchor = orighor, v_anchor = origver) bbox(x, y, w, h; h_anchor = orighor, v_anchor = origver)

View File

@ -185,8 +185,8 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end end
end end
# delegate mimewritable (showable on julia 0.7) to _show instead # delegate showable to _show instead
function Base.mimewritable(m::M, plt::P) where {M<:MIME, P<:Plot} function Base.showable(m::M, plt::P) where {M<:MIME, P<:Plot}
return hasmethod(_show, Tuple{IO, M, P}) return hasmethod(_show, Tuple{IO, M, P})
end end
@ -199,9 +199,13 @@ for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml
"application/eps", "application/pdf", "application/postscript", "application/eps", "application/pdf", "application/postscript",
"application/x-tex") "application/x-tex")
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot) @eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
if haskey(io, :juno_plotsize)
showjuno(io, m, plt)
else
prepare_output(plt) prepare_output(plt)
_show(io, m, plt) _show(io, m, plt)
end end
end
end end
# default text/plain for all backends # default text/plain for all backends
@ -251,112 +255,26 @@ end
# #
# html_output_format("svg") # html_output_format("svg")
# ---------------------------------------------------------
# IJulia
# ---------------------------------------------------------
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
if IJulia.inited
"""
Add extra jupyter mimetypes to display_dict based on the plot backed.
The default is nothing, except for plotly based backends, where it
adds data for `application/vnd.plotly.v1+json` that is used in
frontends like jupyterlab and nteract.
"""
_extra_mime_info!(plt::Plot, out::Dict) = out
function _extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict)
out["application/vnd.plotly.v1+json"] = JSON.lower(plt.o)
out
end
function _extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict)
out["application/vnd.plotly.v1+json"] = Dict(
:data => plotly_series(plt),
:layout => plotly_layout(plt)
)
out
end
function IJulia.display_dict(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
out = Dict()
if output_type == :txt
mime = "text/plain"
out[mime] = sprint(show, MIME(mime), plt)
elseif output_type == :png
mime = "image/png"
out[mime] = base64encode(show, MIME(mime), plt)
elseif output_type == :svg
mime = "image/svg+xml"
out[mime] = sprint(show, MIME(mime), plt)
elseif output_type == :html
mime = "text/html"
out[mime] = sprint(show, MIME(mime), plt)
else
error("Unsupported output type $output_type")
end
_extra_mime_info!(plt, out)
out
end
ENV["MPLBACKEND"] = "Agg"
end
end
# --------------------------------------------------------- # ---------------------------------------------------------
# Atom PlotPane # Atom PlotPane
# --------------------------------------------------------- # ---------------------------------------------------------
@require Juno = "e5e0dc1b-0480-54bc-9374-aad01c23163d" begin function showjuno(io::IO, m, plt)
import Hiccup, Media
if Juno.isactive()
Media.media(Plot, Media.Plot)
function Juno.render(e::Juno.Editor, plt::Plot)
Juno.render(e, nothing)
end
if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes")
function Juno.render(pane::Juno.PlotPane, plt::Plot)
# temporarily overwrite size to be Atom.plotsize
sz = plt[:size] sz = plt[:size]
dpi = plt[:dpi] dpi = plt[:dpi]
thickness_scaling = plt[:thickness_scaling] thickness_scaling = plt[:thickness_scaling]
jsize = Juno.plotsize()
jsize[1] == 0 && (jsize[1] = 400) jsize = get(io, :juno_plotsize, [400, 500])
jsize[2] == 0 && (jsize[2] = 500)
scale = minimum(jsize[i] / sz[i] for i in 1:2) scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = (s * scale for s in sz) plt[:size] = (s * scale for s in sz)
plt[:dpi] = Plots.DPI plt[:dpi] = Plots.DPI
plt[:thickness_scaling] *= scale plt[:thickness_scaling] *= scale
Juno.render(pane, HTML(stringmime(MIME("text/html"), plt)))
prepare_output(plt)
_show(io, m, plt)
plt[:size] = sz plt[:size] = sz
plt[:dpi] = dpi plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling plt[:thickness_scaling] = thickness_scaling
end
# special handling for PlotlyJS
function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend})
display(Plots.PlotsDisplay(), plt)
end
else
function Juno.render(pane::Juno.PlotPane, plt::Plot)
display(Plots.PlotsDisplay(), plt)
s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it."
Juno.render(pane, HTML(s))
end
end
# special handling for plotly... use PlotsDisplay
function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyBackend})
display(Plots.PlotsDisplay(), plt)
s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane."
Juno.render(pane, HTML(s))
end
end
end end

View File

@ -416,7 +416,7 @@ function _process_seriesrecipe(plt::Plot, d::KW)
end end
_process_seriesrecipe(plt, data.d) _process_seriesrecipe(plt, data.d)
else else
warn("Unhandled recipe: $(data)") @warn("Unhandled recipe: $(data)")
break break
end end
end end

View File

@ -579,7 +579,7 @@ end
end end
Plots.@deps stepbins path Plots.@deps stepbins path
wand_edges(x...) = (warn("Load the StatPlots package in order to use :wand bins. Defaulting to :auto", once = true); :auto) wand_edges(x...) = (@warn("Load the StatPlots package in order to use :wand bins. Defaulting to :auto", once = true); :auto)
function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) where N function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) where N
_cl(x) = ceil(Int, NaNMath.max(x, one(x))) _cl(x) = ceil(Int, NaNMath.max(x, one(x)))
@ -619,7 +619,7 @@ _hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) where {
_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) where {N} = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) _hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) where {N} = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning))
_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) where {N} = binning _hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) where {N} = binning
_hist_edges(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) where {N} = _hist_edges(vs::NTuple{N,AbstractVector}, binning::NTuple{N, Any}) where {N} =
map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...,)) map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...,))
_hist_edges(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, AbstractVector}) where {N} = _hist_edges(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, AbstractVector}) where {N} =

View File

@ -5,6 +5,7 @@
const AVec = AbstractVector const AVec = AbstractVector
const AMat = AbstractMatrix const AMat = AbstractMatrix
const KW = Dict{Symbol,Any} const KW = Dict{Symbol,Any}
const TicksArgs = Union{AVec{T}, Tuple{AVec{T}, AVec{S}}, Symbol} where {T<:Real, S<:AbstractString}
struct PlotsDisplay <: AbstractDisplay end struct PlotsDisplay <: AbstractDisplay end
@ -87,7 +88,7 @@ end
Base.getindex(plt::Plot, i::Integer) = plt.subplots[i] Base.getindex(plt::Plot, i::Integer) = plt.subplots[i]
Base.length(plt::Plot) = length(plt.subplots) Base.length(plt::Plot) = length(plt.subplots)
Base.endof(plt::Plot) = length(plt) Base.lastindex(plt::Plot) = length(plt)
Base.getindex(plt::Plot, r::Integer, c::Integer) = plt.layout[r,c] Base.getindex(plt::Plot, r::Integer, c::Integer) = plt.layout[r,c]
Base.size(plt::Plot) = size(plt.layout) Base.size(plt::Plot) = size(plt.layout)
@ -98,6 +99,6 @@ Base.ndims(plt::Plot) = 2
# attr!(plt::Plot, v, k::Symbol) = (plt.attr[k] = v) # attr!(plt::Plot, v, k::Symbol) = (plt.attr[k] = v)
Base.getindex(sp::Subplot, i::Integer) = series_list(sp)[i] Base.getindex(sp::Subplot, i::Integer) = series_list(sp)[i]
Base.endof(sp::Subplot) = length(series_list(sp)) Base.lastindex(sp::Subplot) = length(series_list(sp))
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------

View File

@ -215,15 +215,12 @@ anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError
anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend) anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend)
allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend) allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend)
function Base.start(itr::SegmentsIterator) function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1)
nextidx = 1 nextidx > itr.n && return nothing
if !any(isempty,itr.args) && anynan(1, itr.args) if nextidx == 1 && !any(isempty,itr.args) && anynan(1, itr.args)
_, nextidx = next(itr, 1) nextidx = 2
end end
nextidx
end
Base.done(itr::SegmentsIterator, nextidx::Int) = nextidx > itr.n
function Base.next(itr::SegmentsIterator, nextidx::Int)
i = istart = iend = nextidx i = istart = iend = nextidx
# find the next NaN, and iend is the one before # find the next NaN, and iend is the one before
@ -306,7 +303,7 @@ function _expand_limits(lims, x)
lims[1] = NaNMath.min(lims[1], e1) lims[1] = NaNMath.min(lims[1], e1)
lims[2] = NaNMath.max(lims[2], e2) lims[2] = NaNMath.max(lims[2], e2)
# catch err # catch err
# warn(err) # @warn(err)
catch catch
end end
nothing nothing
@ -412,8 +409,8 @@ function fakedata(sz...)
y y
end end
isijulia() = isdefined(Main, :IJulia) && Main.IJulia.inited isijulia() = :IJulia in nameof.(collect(values(Base.loaded_modules)))
isatom() = isdefined(Main, :Atom) && Main.Atom.isconnected() isatom() = :Atom in nameof.(collect(values(Base.loaded_modules)))
function is_installed(pkgstr::AbstractString) function is_installed(pkgstr::AbstractString)
try try
@ -933,7 +930,7 @@ function attr!(series::Series; kw...)
if haskey(_series_defaults, k) if haskey(_series_defaults, k)
series[k] = v series[k] = v
else else
warn("unused key $k in series attr") @warn("unused key $k in series attr")
end end
end end
_series_updated(series[:subplot].plt, series) _series_updated(series[:subplot].plt, series)
@ -947,7 +944,7 @@ function attr!(sp::Subplot; kw...)
if haskey(_subplot_defaults, k) if haskey(_subplot_defaults, k)
sp[k] = v sp[k] = v
else else
warn("unused key $k in subplot attr") @warn("unused key $k in subplot attr")
end end
end end
sp sp

View File

@ -6,3 +6,4 @@ GR 0.31.0
RDatasets RDatasets
VisualRegressionTests VisualRegressionTests
UnicodePlots UnicodePlots
LaTeXStrings

View File

@ -34,7 +34,7 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is
backend() backend()
# ensure consistent results # ensure consistent results
srand(1234) Random.seed!(1234)
# reference image directory setup # reference image directory setup
# refdir = joinpath(Pkg.dir("ExamplePlots"), "test", "refimg", string(pkg)) # refdir = joinpath(Pkg.dir("ExamplePlots"), "test", "refimg", string(pkg))

View File

@ -3,7 +3,7 @@ module PlotsTests
include("imgcomp.jl") include("imgcomp.jl")
# don't actually show the plots # don't actually show the plots
srand(1234) Random.seed!(1234)
default(show=false, reuse=true) default(show=false, reuse=true)
img_eps = isinteractive() ? 1e-2 : 10e-2 img_eps = isinteractive() ? 1e-2 : 10e-2