From 9ec268928eceaee39cd37e36012a1e3bca2fca3b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 17 Jul 2018 17:41:27 +0200 Subject: [PATCH 1/2] finish refactor --- src/backends.jl | 103 ++++++++++++++++++++++------------------- src/backends/gr.jl | 18 +++---- src/backends/plotly.jl | 16 ++++--- src/themes.jl | 2 +- 4 files changed, 71 insertions(+), 68 deletions(-) diff --git a/src/backends.jl b/src/backends.jl index 3e1affce..8eae6fcc 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -6,6 +6,7 @@ const _backendType = Dict{Symbol, DataType}(:none => NoBackend) const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none) const _backends = Symbol[] const _initialized_backends = Set{Symbol}() +const _default_backends = (:gr, :plotly) "Returns a list of supported backends" backends() = _backends @@ -23,10 +24,11 @@ macro init_backend(s) export $sym $sym(; kw...) = (default(; kw...); backend(Symbol($str))) backend_name(::$T) = Symbol($str) + backend_package_name(::$T) = sym in _default_backends ? :Plots : Symbol("Plots", $(string(s))) push!(_backends, Symbol($str)) _backendType[Symbol($str)] = $T _backendSymbol[$T] = Symbol($str) - include("backends/" * $str * ".jl") + # include("backends/" * $str * ".jl") end) end @@ -135,30 +137,16 @@ CurrentBackend(sym::Symbol) = CurrentBackend(sym, _backend_instance(sym)) function pickDefaultBackend() env_default = get(ENV, "PLOTS_DEFAULT_BACKEND", "") if env_default != "" - if env_default in keys(Pkg.installed()) - sym = Symbol(lowercase(env_default)) - if haskey(_backendType, sym) - return backend(sym) - else - 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 + sym = Symbol(lowercase(env_default)) + if sym in _backends && backend_package_name(sym) in names(Main) + return backend(sym) else - warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not installed.") - end - end - - # 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 - # features, speed, and robustness - for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize") - if pkgstr in keys(Pkg.installed()) - return backend(Symbol(lowercase(pkgstr))) + @warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not supported.") end end # the default if nothing else is installed - backend(:plotly) + backend(:gr) end @@ -174,24 +162,24 @@ function backend() pickDefaultBackend() 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 + # 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 end @@ -199,16 +187,24 @@ end Set the plot backend. """ function backend(pkg::AbstractBackend) - CURRENT_BACKEND.sym = backend_name(pkg) - warn_on_deprecated_backend(CURRENT_BACKEND.sym) - CURRENT_BACKEND.pkg = pkg + if backend_name(pkg) in names(Main) + CURRENT_BACKEND.sym = backend_name(pkg) + warn_on_deprecated_backend(CURRENT_BACKEND.sym) + CURRENT_BACKEND.pkg = pkg + else + @warn("To use $(_backendSymbol[pkg]) you have to run `using $(backend_package_name(pkg))` before.") + end backend() end function backend(modname::Symbol) - warn_on_deprecated_backend(modname) - CURRENT_BACKEND.sym = modname - CURRENT_BACKEND.pkg = _backend_instance(modname) + if modname in _backends + warn_on_deprecated_backend(modname) + CURRENT_BACKEND.sym = modname + CURRENT_BACKEND.pkg = _backend_instance(modname) + else + @warn("`:$modname` is not a supported Plots backend.") + end backend() end @@ -216,7 +212,7 @@ const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse] function warn_on_deprecated_backend(bsym::Symbol) 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 @@ -282,6 +278,15 @@ end @init_backend InspectDR @init_backend HDF5 +_attr = KW() +_seriestype = KW() +_marker = KW() +_style = KW() +_scale = KW() + +include("backends/gr.jl") +include("backends/plotly.jl") + # --------------------------------------------------------- # create the various `is_xxx_supported` and `supported_xxxs` methods @@ -298,10 +303,12 @@ for s in (:attr, :seriestype, :marker, :style, :scale) for bend in backends() bend_type = typeof(_backend_instance(bend)) - v = Symbol("_", bend, "_", s) + + d = Symbol("_", s) + str = string(bend) @eval begin - $f(::$bend_type, $s::Symbol) = $s in $v - $f2(::$bend_type) = $v + $f(::$bend_type, $s::Symbol) = $s in $d[$Symbol($str)] + $f2(::$bend_type) = $d[$Symbol($str)] end end end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index bb962e19..2273b96a 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -2,12 +2,13 @@ # https://github.com/jheinen/GR.jl # significant contributions by @jheinen +import GR @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([ +_attr[:gr] = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, :foreground_color_legend, :foreground_color_grid, :foreground_color_axis, @@ -47,15 +48,15 @@ const _gr_attr = merge_with_base_supported([ :camera, :contour_labels, ]) -const _gr_seriestype = [ +_seriestype[:gr] = [ :path, :scatter, :straightline, :heatmap, :pie, :image, :contour, :path3d, :scatter3d, :surface, :wireframe, :shape ] -const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] -const _gr_marker = _allMarkers -const _gr_scale = [:identity, :log10] +_style[:gr] = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] +_marker[:gr] = _allMarkers +_scale[:gr] = [:identity, :log10] is_marker_supported(::GRBackend, shape::Shape) = true function add_backend_string(::GRBackend) @@ -65,13 +66,6 @@ function add_backend_string(::GRBackend) """ end -function _initialize_backend(::GRBackend; kw...) - @eval begin - import GR - export GR - end -end - # -------------------------------------------------------------------------------------- const gr_linetype = KW( diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 0b4c44d4..ca9809d6 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -5,7 +5,9 @@ Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl")) end -const _plotly_attr = merge_with_base_supported([ +using UUIDs + +_attr[:plotly] = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, :foreground_color_legend, :foreground_color_guide, @@ -48,17 +50,17 @@ const _plotly_attr = merge_with_base_supported([ :contour_labels, ]) -const _plotly_seriestype = [ +_seriestype[:plotly] = [ :path, :scatter, :pie, :heatmap, :contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl, :straightline ] -const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot] -const _plotly_marker = [ +_style[:plotly] = [:auto, :solid, :dash, :dot, :dashdot] +_marker[:plotly] = [ :none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :pentagon, :hexagon, :octagon, :vline, :hline ] -const _plotly_scale = [:identity, :log10] +_scale[:plotly] = [:identity, :log10] is_subplot_supported(::PlotlyBackend) = true # is_string_supported(::PlotlyBackend) = true const _plotly_framestyles = [:box, :axes, :zerolines, :grid, :none] @@ -720,7 +722,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) (isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple)) segments = iter_segments(series) - d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments)) + d_outs = Vector{KW}(undef, (hasfillrange ? 2 : 1 ) * length(segments)) for (i,rng) in enumerate(segments) !isscatter && length(rng) < 2 && continue @@ -906,7 +908,7 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing) w, h = plt[:size] style = "width:$(w)px;height:$(h)px;" end - uuid = Base.Random.uuid4() + uuid = UUIDs.uuid4() html = """