Compare commits

..

3 Commits

Author SHA1 Message Date
Josef Heinen b9c9fc615b Update gr.jl 2018-08-01 13:06:55 +02:00
Daniel Schwabeneder 50c62ec48e Merge pull request #1593 from fredrikekre/fe/0.72
small additional fixes for 0.7
2018-07-05 08:14:48 +02:00
Fredrik Ekre b16ced0367 small fixes 2018-07-05 00:19:21 +02:00
40 changed files with 622 additions and 722 deletions
-1
View File
@@ -5,4 +5,3 @@
examples/.ipynb_checkpoints/*
examples/meetup/.ipynb_checkpoints/*
deps/plotly-latest.min.js
deps/build.log
+5 -6
View File
@@ -4,11 +4,10 @@ os:
- linux
# - osx
julia:
# - 0.7
- nightly
# matrix:
# allow_failures:
# - julia: nightly
- 0.7
matrix:
allow_failures:
- julia: nightly
# # before install:
# # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
@@ -45,7 +44,7 @@ notifications:
# uncomment the following lines to override the default test script
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'import Pkg; Pkg.add(Pkg.PackageSpec(path=pwd())); Pkg.build("Plots")'
- julia -e 'using Pkg; Pkg.add(pwd()); Pkg.build("Plots")'
- julia test/travis_commands.jl
# - julia -e 'Pkg.clone("ImageMagick"); Pkg.build("ImageMagick")'
# - julia -e 'Pkg.clone("GR"); Pkg.build("GR")'
+1 -17
View File
@@ -10,23 +10,7 @@
---
## (current master)
- All new development should target Julia 1.x!
## 0.19.2
- several small fixes for 1.0 compatibility
## 0.19.1
- don't broadcast plot_color
## 0.19.0
- Refactor conditional loading to use Requires
- Many fixes for 1.0 compatibility
## 0.18.0
- update minor version to 0.7
## 0.17.4
- fix thickness_scaling for pyplot
- All new development should target Julia 0.7!
## 0.17.3
- Log-scale heatmap edge computation
+1 -1
View File
@@ -1,4 +1,4 @@
julia 0.7
julia 0.7-alpha
RecipesBase 0.2.3
PlotUtils 0.4.1
+7 -6
View File
@@ -1,14 +1,15 @@
environment:
matrix:
# - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
# - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
# matrix:
# allow_failures:
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
matrix:
allow_failures:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" #check and address
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
notifications:
- provider: Email
+6 -6
View File
@@ -1,3 +1,5 @@
__precompile__(true)
module Plots
using Reexport
@@ -5,7 +7,6 @@ using Reexport
import StaticArrays
using StaticArrays.FixedSizeArrays
using Dates, Printf, Statistics, Base64, LinearAlgebra
import SparseArrays: findnz
@reexport using RecipesBase
import RecipesBase: plot, plot!, animate
@@ -170,7 +171,6 @@ include("arg_desc.jl")
include("plotattr.jl")
include("backends.jl")
include("output.jl")
include("init.jl")
# ---------------------------------------------------------
@@ -236,10 +236,10 @@ zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmi
"Set xticks for an existing plot"
xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
xticks!(v::AVec{T}; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
"Set yticks for an existing plot"
yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
yticks!(v::AVec{T}; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
xticks!(
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
@@ -274,8 +274,8 @@ let PlotOrSubplot = Union{Plot, Subplot}
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 zlims!(plt::PlotOrSubplot, zmin::Real, zmax::Real; kw...) = plot!(plt; zlims = (zmin,zmax), kw...)
global xticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; xticks = ticks, kw...)
global yticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; yticks = ticks, kw...)
global xticks!(plt::PlotOrSubplot, ticks::AVec{T}; 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 xticks!(plt::PlotOrSubplot,
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks,labels), kw...)
global yticks!(plt::PlotOrSubplot,
+3 -3
View File
@@ -87,7 +87,7 @@ function buildanimation(animdir::AbstractString, fn::AbstractString,
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
end
show_msg && @info("Saved animation to ", fn)
show_msg && info("Saved animation to ", fn)
AnimatedGif(fn)
end
@@ -142,7 +142,7 @@ function _animate(forloop::Expr, args...; callgif = false)
end
push!(block.args, :(if $filterexpr; frame($animsym); end))
push!(block.args, :(global $countersym += 1))
push!(block.args, :($countersym += 1))
# add a final call to `gif(anim)`?
retval = callgif ? :(gif($animsym)) : animsym
@@ -151,7 +151,7 @@ function _animate(forloop::Expr, args...; callgif = false)
esc(quote
$freqassert # if filtering, check frequency is an Integer > 0
$animsym = Animation() # init animation object
global $countersym = 1 # init iteration counter
$countersym = 1 # init iteration counter
$forloop # for loop, saving a frame after each iteration
$retval # return the animation object, or the gif
end)
+1 -7
View File
@@ -21,7 +21,7 @@ const _arg_desc = KW(
:markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)",
:markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.",
:markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.",
:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(min(x), stop = extrema(x), length = 25)`",
:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `linspace(extrema(x)..., 25)`",
:smooth => "Bool. Add a regression line?",
:group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.",
:x => "Various. Input data. First Dimension",
@@ -139,12 +139,6 @@ const _arg_desc = KW(
:gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.",
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
:foreground_color_minor_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of minor grid lines.",
:minorgrid => "Bool. Adds minor grid lines and ticks to the plot. Set minorticks to change number of gridlines",
:minorticks => "Integer. Intervals to divide the gap between major ticks into",
:minorgridalpha => "Number in [0,1]. The alpha/opacity override for the minorgrid lines.",
:minorgridstyle => "Symbol. Style of the minor grid lines. Choose from $(_allStyles)",
:minorgridlinewidth => "Number. Width of the minor grid lines (in pixels)",
:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`",
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
:widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.",
+20 -84
View File
@@ -194,7 +194,7 @@ function hasgrid(arg::Symbol, letter)
if arg in _allGridSyms
arg in (:all, :both, :on) || occursin(string(letter), string(arg))
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
end
end
@@ -212,7 +212,7 @@ function showaxis(arg::Symbol, letter)
if arg in _allGridSyms
arg in (:all, :both, :on, :yes) || occursin(string(letter), string(arg))
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
end
end
@@ -380,13 +380,7 @@ const _axis_defaults = KW(
:gridalpha => 0.1,
:gridstyle => :solid,
:gridlinewidth => 0.5,
:foreground_color_minor_grid => :match, # grid color
:minorgridalpha => 0.05,
:minorgridstyle => :solid,
:minorgridlinewidth => 0.5,
:tick_direction => :in,
:minorticks => false,
:minorgrid => false,
:showaxis => true,
:widen => true,
)
@@ -504,8 +498,6 @@ add_aliases(:foreground_color_subplot, :fg_subplot, :fgsubplot, :fgcolor_subplot
:foreground_colour_subplot, :fgcolour_subplot, :fg_colour_subplot)
add_aliases(:foreground_color_grid, :fg_grid, :fggrid, :fgcolor_grid, :fg_color_grid, :foreground_grid,
:foreground_colour_grid, :fgcolour_grid, :fg_colour_grid, :gridcolor)
add_aliases(:foreground_color_minor_grid, :fg_minor_grid, :fgminorgrid, :fgcolor_minorgrid, :fg_color_minorgrid, :foreground_minorgrid,
:foreground_colour_minor_grid, :fgcolour_minorgrid, :fg_colour_minor_grid, :minorgridcolor)
add_aliases(:foreground_color_title, :fg_title, :fgtitle, :fgcolor_title, :fg_color_title, :foreground_title,
:foreground_colour_title, :fgcolour_title, :fg_colour_title, :titlecolor)
add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis,
@@ -582,8 +574,6 @@ add_aliases(:inset_subplots, :inset, :floating)
add_aliases(:stride, :wirefame_stride, :surface_stride, :surf_str, :str)
add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw)
add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls)
add_aliases(:minorgridlinewidth, :minorgridwidth, :minorgrid_linewidth, :minorgrid_width, :minorgridlw, :minorgrid_lw)
add_aliases(:minorgridstyle, :minorgrid_style, :minorgridlinestyle, :minorgrid_linestyle, :minorgrid_ls, :minorgridls)
add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border)
add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor)
add_aliases(:camera, :cam, :viewangle, :view_angle)
@@ -704,7 +694,7 @@ function processLineArg(d::KW, arg)
# color
elseif !handleColors!(d, arg, :linecolor)
@warn("Skipped line arg $arg.")
warn("Skipped line arg $arg.")
end
end
@@ -740,7 +730,7 @@ function processMarkerArg(d::KW, arg)
# markercolor
elseif !handleColors!(d, arg, :markercolor)
@warn("Skipped marker arg $arg.")
warn("Skipped marker arg $arg.")
end
end
@@ -800,44 +790,11 @@ function processGridArg!(d::KW, arg, letter)
# color
elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid))
@warn("Skipped grid arg $arg.")
warn("Skipped grid arg $arg.")
end
end
function processMinorGridArg!(d::KW, arg, letter)
if arg in _allGridArgs || isa(arg, Bool)
d[Symbol(letter, :minorgrid)] = hasgrid(arg, letter)
elseif allStyles(arg)
d[Symbol(letter, :minorgridstyle)] = arg
d[Symbol(letter, :minorgrid)] = true
elseif typeof(arg) <: Stroke
arg.width == nothing || (d[Symbol(letter, :minorgridlinewidth)] = arg.width)
arg.color == nothing || (d[Symbol(letter, :foreground_color_minor_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color))
arg.alpha == nothing || (d[Symbol(letter, :minorgridalpha)] = arg.alpha)
arg.style == nothing || (d[Symbol(letter, :minorgridstyle)] = arg.style)
d[Symbol(letter, :minorgrid)] = true
# linealpha
elseif allAlphas(arg)
d[Symbol(letter, :minorgridalpha)] = arg
d[Symbol(letter, :minorgrid)] = true
# linewidth
elseif allReals(arg)
d[Symbol(letter, :minorgridlinewidth)] = arg
d[Symbol(letter, :minorgrid)] = true
# color
elseif handleColors!(d, arg, Symbol(letter, :foreground_color_minor_grid))
d[Symbol(letter, :minorgrid)] = true
else
@warn("Skipped grid arg $arg.")
end
end
function processFontArg!(d::KW, fontname::Symbol, arg)
T = typeof(arg)
if T <: Font
@@ -867,7 +824,7 @@ function processFontArg!(d::KW, fontname::Symbol, arg)
elseif typeof(arg) <: Real
d[Symbol(fontname, :rotation)] = convert(Float64, arg)
else
@warn("Skipped font arg: $arg ($(typeof(arg)))")
warn("Skipped font arg: $arg ($(typeof(arg)))")
end
end
@@ -937,21 +894,7 @@ function preprocessArgs!(d::KW)
processGridArg!(d, arg, letter)
end
end
# handle minor grid args common to all axes
args = pop!(d, :minorgrid, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
processMinorGridArg!(d, arg, letter)
end
end
# handle individual axes grid args
for letter in (:x, :y, :z)
gridsym = Symbol(letter, :minorgrid)
args = pop!(d, gridsym, ())
for arg in wraptuple(args)
processMinorGridArg!(d, arg, letter)
end
end
# fonts
for fontname in (:titlefont, :legendfont)
args = pop!(d, fontname, ())
@@ -1050,7 +993,7 @@ function preprocessArgs!(d::KW)
# warnings for moved recipes
st = get(d, :seriestype, :path)
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
return
@@ -1070,7 +1013,7 @@ function extractGroupArgs(v::AVec, args...; legendEntry = string)
groupLabels = sort(collect(unique(v)))
n = length(groupLabels)
if n > 100
@warn("You created n=$n groups... Is that intended?")
warn("You created n=$n groups... Is that intended?")
end
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
GroupBy(map(legendEntry, groupLabels), groupIds)
@@ -1142,7 +1085,7 @@ function warnOnUnsupported_args(pkg::AbstractBackend, d::KW)
if !isempty(_to_warn)
for k in sort(collect(_to_warn))
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
@@ -1153,13 +1096,13 @@ end
function warnOnUnsupported(pkg::AbstractBackend, d::KW)
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
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
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
@@ -1168,7 +1111,7 @@ function warnOnUnsupported_scales(pkg::AbstractBackend, d::KW)
if haskey(d, k)
v = d[k]
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
@@ -1279,7 +1222,6 @@ const _match_map2 = KW(
:foreground_color_axis => :foreground_color_subplot,
:foreground_color_border => :foreground_color_subplot,
:foreground_color_grid => :foreground_color_subplot,
:foreground_color_minor_grid=> :foreground_color_subplot,
:foreground_color_guide => :foreground_color_subplot,
:foreground_color_text => :foreground_color_subplot,
:fontfamily_subplot => :fontfamily,
@@ -1467,7 +1409,6 @@ function _update_axis_colors(axis::Axis)
color_or_nothing!(axis.d, :foreground_color_guide)
color_or_nothing!(axis.d, :foreground_color_text)
color_or_nothing!(axis.d, :foreground_color_grid)
color_or_nothing!(axis.d, :foreground_color_minor_grid)
return
end
@@ -1521,11 +1462,6 @@ function getSeriesRGBColor(c, sp::Subplot, n::Int)
plot_color(c)
end
function getSeriesRGBColor(c::AbstractArray, sp::Subplot, n::Int)
@info "it is surprising that this function is called - please report a use case as a Plots issue"
map(x->getSeriesRGBColor(x, sp, n), c)
end
function ensure_gradient!(d::KW, csym::Symbol, asym::Symbol)
if !isa(d[csym], ColorGradient)
d[csym] = typeof(d[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = d[asym])
@@ -1568,21 +1504,21 @@ function _update_series_attributes!(d::KW, plt::Plot, sp::Subplot)
end
# update series color
d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], sp, plotIndex)
d[:seriescolor] = getSeriesRGBColor.(d[:seriescolor], Ref(sp), plotIndex)
# update other colors
for s in (:line, :marker, :fill)
csym, asym = Symbol(s,:color), Symbol(s,:alpha)
d[csym] = if d[csym] == :auto
plot_color(if has_black_border_for_default(d[:seriestype]) && s == :line
plot_color.(if has_black_border_for_default(d[:seriestype]) && s == :line
sp[:foreground_color_subplot]
else
d[:seriescolor]
end)
elseif d[csym] == :match
plot_color(d[:seriescolor])
plot_color.(d[:seriescolor])
else
getSeriesRGBColor(d[csym], sp, plotIndex)
getSeriesRGBColor.(d[csym], sp, plotIndex)
end
end
@@ -1590,9 +1526,9 @@ function _update_series_attributes!(d::KW, plt::Plot, sp::Subplot)
d[:markerstrokecolor] = if d[:markerstrokecolor] == :match
plot_color(sp[:foreground_color_subplot])
elseif d[:markerstrokecolor] == :auto
getSeriesRGBColor(d[:markercolor], sp, plotIndex)
getSeriesRGBColor.(d[:markercolor], sp, plotIndex)
else
getSeriesRGBColor(d[:markerstrokecolor], sp, plotIndex)
getSeriesRGBColor.(d[:markerstrokecolor], sp, plotIndex)
end
# if marker_z, fill_z or line_z are set, ensure we have a gradient
+2 -77
View File
@@ -80,7 +80,7 @@ function process_axis_arg!(d::KW, arg, letter = "")
d[Symbol(letter,:formatter)] = arg
elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_axis))
@warn("Skipped $(letter)axis arg $arg")
warn("Skipped $(letter)axis arg $arg")
end
end
@@ -286,34 +286,6 @@ _transform_ticks(ticks) = ticks
_transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.value.(ticks)
_transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2])
function get_minor_ticks(axis,ticks)
axis[:minorticks] in (nothing, false) && !axis[:minorgrid] && return nothing
ticks = ticks[1]
length(ticks) < 2 && return nothing
amin, amax = axis_limits(axis)
#Add one phantom tick either side of the ticks to ensure minor ticks extend to the axis limits
if length(ticks) > 2
ratio = (ticks[3] - ticks[2])/(ticks[2] - ticks[1])
elseif axis[:scale] == :none
ratio = 1
else
return nothing
end
first_step = ticks[2] - ticks[1]
last_step = ticks[end] - ticks[end-1]
ticks = [ticks[1] - first_step/ratio; ticks; ticks[end] + last_step*ratio]
#Default to 5 intervals between major ticks
n = typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ? axis[:minorticks] : 5
minorticks = typeof(ticks[1])[]
for (i,hi) in enumerate(ticks[2:end])
lo = ticks[i]
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
end
minorticks[amin .<= minorticks .<= amax]
end
# -------------------------------------------------------------------------
@@ -590,16 +562,12 @@ function axis_drawing_info(sp::Subplot)
ymin, ymax = axis_limits(yaxis)
xticks = get_ticks(xaxis)
yticks = get_ticks(yaxis)
xminorticks = get_minor_ticks(xaxis,xticks)
yminorticks = get_minor_ticks(yaxis,yticks)
xaxis_segs = Segments(2)
yaxis_segs = Segments(2)
xtick_segs = Segments(2)
ytick_segs = Segments(2)
xgrid_segs = Segments(2)
ygrid_segs = Segments(2)
xminorgrid_segs = Segments(2)
yminorgrid_segs = Segments(2)
xborder_segs = Segments(2)
yborder_segs = Segments(2)
@@ -642,28 +610,6 @@ function axis_drawing_info(sp::Subplot)
xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
end
end
if !(xaxis[:minorticks] in (nothing, false)) || xaxis[:minorgrid]
f = scalefunc(yaxis[:scale])
invf = invscalefunc(yaxis[:scale])
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t1 = invf(f(ymin) + 0.01 * (f(ymax) - f(ymin)) * ticks_in)
t2 = invf(f(ymax) - 0.01 * (f(ymax) - f(ymin)) * ticks_in)
t3 = invf(f(0) + 0.01 * (f(ymax) - f(ymin)) * ticks_in)
for xminortick in xminorticks
if xaxis[:showaxis]
tick_start, tick_stop = if sp[:framestyle] == :origin
(0, t3)
else
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1)
end
push!(xtick_segs, (xminortick, tick_start), (xminortick, tick_stop)) # bottom tick
end
# sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick
xaxis[:minorgrid] && push!(xminorgrid_segs, (xminortick, ymin), (xminortick, ymax)) # vertical grid
end
end
# yaxis
if yaxis[:showaxis]
@@ -703,28 +649,7 @@ function axis_drawing_info(sp::Subplot)
yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
end
if !(yaxis[:minorticks] in (nothing, false)) || yaxis[:minorgrid]
f = scalefunc(xaxis[:scale])
invf = invscalefunc(xaxis[:scale])
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
t1 = invf(f(xmin) + 0.01 * (f(xmax) - f(xmin)) * ticks_in)
t2 = invf(f(xmax) - 0.01 * (f(xmax) - f(xmin)) * ticks_in)
t3 = invf(f(0) + 0.01 * (f(xmax) - f(xmin)) * ticks_in)
for ytick in yminorticks
if yaxis[:showaxis]
tick_start, tick_stop = if sp[:framestyle] == :origin
(0, t3)
else
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1)
end
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
end
# sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick
yaxis[:minorgrid] && push!(yminorgrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
end
end
xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs
xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs
end
+43 -153
View File
@@ -6,8 +6,6 @@ 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 = (:none, :gr, :plotly)
const _backendPackage = Dict{Symbol, Symbol}()
"Returns a list of supported backends"
backends() = _backends
@@ -15,12 +13,9 @@ backends() = _backends
"Returns the name of the current backend"
backend_name() = CURRENT_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)
package_str = string(s)
str = lowercase(package_str)
str = lowercase(string(s))
sym = Symbol(str)
T = Symbol(string(s) * "Backend")
esc(quote
@@ -28,25 +23,24 @@ macro init_backend(s)
export $sym
$sym(; kw...) = (default(; kw...); backend(Symbol($str)))
backend_name(::$T) = Symbol($str)
backend_package_name(pkg::$T) = backend_package_name(Symbol($str))
push!(_backends, Symbol($str))
_backendType[Symbol($str)] = $T
_backendSymbol[$T] = Symbol($str)
_backendPackage[Symbol($str)] = Symbol($package_str)
# include("backends/" * $str * ".jl")
include("backends/" * $str * ".jl")
end)
end
# include("backends/web.jl")
include("backends/web.jl")
# include("backends/supported.jl")
# ---------------------------------------------------------
function add_backend(pkg::Symbol)
@info("To do a standard install of $pkg, copy and run this:\n\n")
info("To do a standard install of $pkg, copy and run this:\n\n")
println(add_backend_string(_backend_instance(pkg)))
println()
end
add_backend_string(b::AbstractBackend) = warn("No custom install defined for $(backend_name(b))")
# don't do anything as a default
_create_backend_figure(plt::Plot) = nothing
@@ -141,30 +135,30 @@ CurrentBackend(sym::Symbol) = CurrentBackend(sym, _backend_instance(sym))
function pickDefaultBackend()
env_default = get(ENV, "PLOTS_DEFAULT_BACKEND", "")
if env_default != ""
sym = Symbol(lowercase(env_default))
if sym in _backends
if sym in _initialized_backends
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 `$(backend_package_name(sym))` is not loaded.")
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
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"))
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)))
# end
# end
for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize")
if pkgstr in keys(Pkg.installed())
return backend(Symbol(lowercase(pkgstr)))
end
end
# the default if nothing else is installed
backend(:gr)
backend(:plotly)
end
@@ -180,6 +174,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
CURRENT_BACKEND.pkg
end
@@ -187,29 +199,16 @@ end
Set the plot backend.
"""
function backend(pkg::AbstractBackend)
sym = backend_name(pkg)
if sym in _initialized_backends
CURRENT_BACKEND.sym = backend_name(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
CURRENT_BACKEND.sym = backend_name(pkg)
warn_on_deprecated_backend(CURRENT_BACKEND.sym)
CURRENT_BACKEND.pkg = pkg
backend()
end
function backend(sym::Symbol)
if sym in _backends
backend(_backend_instance(sym))
else
@warn("`:$sym` is not a supported backend.")
end
function backend(modname::Symbol)
warn_on_deprecated_backend(modname)
CURRENT_BACKEND.sym = modname
CURRENT_BACKEND.pkg = _backend_instance(modname)
backend()
end
@@ -217,7 +216,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
@@ -309,112 +308,3 @@ end
# is_subplot_supported(::AbstractBackend) = false
# 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")
Pkg.add("PyCall")
Pkg.add("LaTeXStrings")
withenv("PYTHON" => "") do
Pkg.build("PyCall")
Pkg.build("PyPlot")
end
"""
end
# ------------------------------------------------------------------------------
# unicodeplots
function add_backend_string(::UnicodePlotsBackend)
"""
using Pkg
Pkg.add("UnicodePlots")
Pkg.build("UnicodePlots")
"""
end
+36 -15
View File
@@ -9,6 +9,10 @@ TODO
* 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([
:annotations,
:background_color_legend, :background_color_inside, :background_color_outside,
@@ -57,11 +61,36 @@ const _glvisualize_style = [:auto, :solid, :dash, :dot, :dashdot]
const _glvisualize_marker = _allMarkers
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
GL = Plots
# --------------------------------------------------------------------------------------
function _initialize_backend(::GLVisualizeBackend; kw...)
@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
# ---------------------------------------------------------------------------
@@ -667,7 +696,7 @@ function text_model(font, pivot)
end
end
function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area)
xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp)
xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp)
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid]))
@@ -681,14 +710,6 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are
grid = draw_grid_lines(sp, ygrid_segs, yaxis[:gridlinewidth], yaxis[:gridstyle], model, RGBA(ygc, yaxis[:gridalpha]))
push!(axis_vis, grid)
end
if xaxis[:minorgrid]
minorgrid = draw_minorgrid_lines(sp, xminorgrid_segs, xaxis[:minorgridlinewidth], xaxis[:minorgridstyle], model, RGBA(xgc, xaxis[:minorgridalpha]))
push!(axis_vis, minorgrid)
end
if yaxis[:minorgrid]
minorgrid = draw_minorgrid_lines(sp, yminorgrid_segs, yaxis[:minorgridlinewidth], yaxis[:minorgridstyle], model, RGBA(ygc, yaxis[:minorgridalpha]))
push!(axis_vis, minorgrid)
end
xac = Colors.color(Plots.gl_color(xaxis[:foreground_color_axis]))
yac = Colors.color(Plots.gl_color(yaxis[:foreground_color_axis]))
@@ -1300,7 +1321,7 @@ function gl_poly(points, kw_args)
if !isempty(GeometryTypes.faces(mesh)) # check if polygonation has any faces
push!(result, GLVisualize.visualize(mesh, Style(:default), kw_args))
else
@warn("Couldn't draw the polygon: $points")
warn("Couldn't draw the polygon: $points")
end
end
result
+21 -25
View File
@@ -3,6 +3,10 @@
# 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([
:annotations,
:background_color_legend, :background_color_inside, :background_color_outside,
@@ -61,8 +65,12 @@ function add_backend_string(::GRBackend)
"""
end
import GR
export GR
function _initialize_backend(::GRBackend; kw...)
@eval begin
import GR
export GR
end
end
# --------------------------------------------------------------------------------------
@@ -616,7 +624,7 @@ end
function _update_min_padding!(sp::Subplot{GRBackend})
dpi = sp.plt[:thickness_scaling]
if !haskey(ENV, "GKSwstype")
if isijulia()
if isijulia() || (isdefined(Main, :Juno) && Juno.isactive())
ENV["GKSwstype"] = "svg"
end
end
@@ -810,7 +818,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.setwindow(xmin, xmax, ymin, ymax)
end
xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp)
xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp)
# @show xticks yticks #spine_segs grid_segs
# draw the grid lines
@@ -826,18 +834,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
gr_set_transparency(yaxis[:gridalpha])
gr_polyline(coords(ygrid_segs)...)
end
if xaxis[:minorgrid]
# gr_set_linecolor(sp[:foreground_color_grid])
# GR.grid(xtick, ytick, 0, 0, majorx, majory)
gr_set_line(xaxis[:minorgridlinewidth], xaxis[:minorgridstyle], xaxis[:foreground_color_minor_grid])
gr_set_transparency(xaxis[:minorgridalpha])
gr_polyline(coords(xminorgrid_segs)...)
end
if yaxis[:minorgrid]
gr_set_line(yaxis[:minorgridlinewidth], yaxis[:minorgridstyle], yaxis[:foreground_color_minor_grid])
gr_set_transparency(yaxis[:minorgridalpha])
gr_polyline(coords(yminorgrid_segs)...)
end
gr_set_transparency(1.0)
# axis lines
@@ -1103,10 +1099,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.setspace(zmin, zmax, 0, 90)
grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad()
colors = [plot_color(grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)], series[:fillalpha]) for zi=z]
rgba = map(c -> UInt32( round(UInt, alpha(c) * 255) << 24 +
round(UInt, blue(c) * 255) << 16 +
round(UInt, green(c) * 255) << 8 +
round(UInt, red(c) * 255) ), colors)
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) ), colors)
w, h = length(x), length(y)
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
@@ -1210,12 +1206,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y])
if eltype(z) <: Colors.AbstractGray
grey = round.(UInt8, float(z) * 255)
rgba = map(c -> UInt32( 0xff000000 + UInt(c)<<16 + UInt(c)<<8 + UInt(c) ), grey)
rgba = map(c -> UInt32( 0xff000000 + Int(c)<<16 + Int(c)<<8 + Int(c) ), grey)
else
rgba = map(c -> UInt32( round(UInt, alpha(c) * 255) << 24 +
round(UInt, blue(c) * 255) << 16 +
round(UInt, green(c) * 255) << 8 +
round(UInt, red(c) * 255) ), z)
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) ), z)
end
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
end
+57 -41
View File
@@ -28,6 +28,10 @@ Read from .hdf5 file using:
- 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
#Dispatch types:
@@ -41,7 +45,6 @@ end
#==Useful constants
===============================================================================#
const _hdf5_nullable{T} = Union{T, Nothing}
const _hdf5_plotroot = "plot"
const _hdf5_dataroot = "data" #TODO: Eventually move data to different root (easier to locate)?
const _hdf5plot_datatypeid = "TYPE" #Attribute identifying type
@@ -105,35 +108,12 @@ const _hdf5_marker = vcat(_allMarkers, :pixel)
const _hdf5_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::HDF5Backend, shape::Shape) = true
if length(HDF5PLOT_MAP_TELEM2STR) < 1
#Possible element types of high-level data types:
telem2str = Dict{String, Type}(
"NATIVE" => HDF5PlotNative,
"VOID" => Nothing,
"BOOL" => Bool,
"SYMBOL" => Symbol,
"TUPLE" => Tuple,
"CTUPLE" => HDF5CTuple, #Tuple of complex structures
"RGBA" => ARGB{N0f8},
"EXTREMA" => Extrema,
"LENGTH" => Length,
"ARRAY" => Array, #Dict won't allow Array to be key in HDF5PLOT_MAP_TELEM2STR
#Sub-structure types:
"FONT" => Font,
"BOUNDINGBOX" => BoundingBox,
"GRIDLAYOUT" => GridLayout,
"ROOTLAYOUT" => RootLayout,
"SERIESANNOTATIONS" => SeriesAnnotations,
# "PLOTTEXT" => PlotText,
"COLORGRADIENT" => ColorGradient,
"AXIS" => Axis,
"SURFACE" => Surface,
"SUBPLOT" => Subplot,
"NULLABLE" => _hdf5_nullable,
)
merge!(HDF5PLOT_MAP_STR2TELEM, telem2str)
merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM))
function add_backend_string(::HDF5Backend)
"""
if !Plots.is_installed("HDF5")
Pkg.add("HDF5")
end
"""
end
@@ -160,6 +140,44 @@ 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:
telem2str = Dict{String, Type}(
"NATIVE" => HDF5PlotNative,
"VOID" => Nothing,
"BOOL" => Bool,
"SYMBOL" => Symbol,
"TUPLE" => Tuple,
"CTUPLE" => HDF5CTuple, #Tuple of complex structures
"RGBA" => ARGB{N0f8},
"EXTREMA" => Extrema,
"LENGTH" => Length,
"ARRAY" => Array, #Dict won't allow Array to be key in HDF5PLOT_MAP_TELEM2STR
#Sub-structure types:
"FONT" => Font,
"BOUNDINGBOX" => BoundingBox,
"GRIDLAYOUT" => GridLayout,
"ROOTLAYOUT" => RootLayout,
"SERIESANNOTATIONS" => SeriesAnnotations,
# "PLOTTEXT" => PlotText,
"COLORGRADIENT" => ColorGradient,
"AXIS" => Axis,
"SURFACE" => Surface,
"SUBPLOT" => Subplot,
"NULLABLE" => Nullable,
)
merge!(HDF5PLOT_MAP_STR2TELEM, telem2str)
merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM))
end
end
end
# ---------------------------------------------------------------------------
# Create the window/figure for this backend.
function _create_backend_figure(plt::Plot{HDF5Backend})
@@ -226,7 +244,7 @@ end
function _display(plt::Plot{HDF5Backend})
msg = "HDF5 interface does not support `display()` function."
msg *= "\nUse `Plots.hdf5plot_write(::String)` method to write to .HDF5 \"plot\" file instead."
@warn(msg)
warn(msg)
return
end
@@ -271,7 +289,7 @@ function _hdf5plot_writecount(grp, n::Int) #Write directly to group
end
function _hdf5plot_gwritefields(grp, k::String, v)
grp = HDF5.g_create(grp, k)
for _k in fieldnames(typeof(v))
for _k in fieldnames(v)
_v = getfield(v, _k)
kstr = string(_k)
_hdf5plot_gwrite(grp, kstr, _v)
@@ -294,7 +312,7 @@ end
#=
function _hdf5plot_gwrite(grp, k::String, v::Array{Any})
# @show grp, k
@warn("Cannot write Array: $k=$v")
warn("Cannot write Array: $k=$v")
end
=#
function _hdf5plot_gwrite(grp, k::String, v::Nothing)
@@ -324,7 +342,7 @@ function _hdf5plot_gwrite(grp, k::String, v::Tuple)
#NOTE: _hdf5plot_overwritetype overwrites "Array" type with "Tuple".
end
function _hdf5plot_gwrite(grp, k::String, d::Dict)
# @warn("Cannot write dict: $k=$d")
# warn("Cannot write dict: $k=$d")
end
function _hdf5plot_gwrite(grp, k::String, v::AbstractRange)
_hdf5plot_gwrite(grp, k, collect(v)) #For now
@@ -345,10 +363,9 @@ function _hdf5plot_gwritearray(grp, k::String, v::Array{T}) where T
vgrp = HDF5.g_create(grp, k)
_hdf5plot_writetype(vgrp, Array) #ANY
sz = size(v)
lidx = LinearIndices(sz)
for iter in eachindex(v)
coord = lidx[iter]
coord = LinearIndices(sz, iter)
elem = v[iter]
idxstr = join(coord, "_")
_hdf5plot_gwrite(vgrp, "v$idxstr", v[iter])
@@ -393,7 +410,7 @@ function _hdf5plot_gwrite(grp, k::String, v::Surface)
_hdf5plot_writetype(grp, Surface)
end
# #TODO: "Properly" support Nullable using _hdf5plot_writetype?
# function _hdf5plot_gwrite(grp, k::String, v::_hdf5_nullable)
# function _hdf5plot_gwrite(grp, k::String, v::Nullable)
# if isnull(v)
# _hdf5plot_gwrite(grp, k, nothing)
# else
@@ -510,11 +527,10 @@ function _hdf5plot_read(grp, k::String, T::Type{Array}, dtid) #ANY
sz = _hdf5plot_read(grp, "dim")
if [0] == sz; return []; end
sz = tuple(sz...)
result = Array{Any}(undef, sz)
lidx = LinearIndices(sz)
result = Array{Any}(sz)
for iter in eachindex(result)
coord = lidx[iter]
coord = LinearIndices(sz, iter)
idxstr = join(coord, "_")
result[iter] = _hdf5plot_read(grp, "v$idxstr")
end
@@ -589,7 +605,7 @@ function _hdf5plot_read(grp, d::Dict)
catch e
@show e
@show grp
@warn("Could not read field $k")
warn("Could not read field $k")
end
end
return
+32 -14
View File
@@ -13,6 +13,10 @@ Add in functionality to Plots.jl:
: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
const _inspectdr_attr = merge_with_base_supported([
@@ -148,23 +152,37 @@ end
# ---------------------------------------------------------------------------
#Glyph used when plotting "Shape"s:
INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y
)
mutable struct InspecDRPlotRef
mplot::Union{Nothing, InspectDR.Multiplot}
gui::Union{Nothing, InspectDR.GtkPlot}
function add_backend_string(::InspectDRBackend)
"""
if !Plots.is_installed("InspectDR")
Pkg.add("InspectDR")
end
"""
end
_inspectdr_getmplot(::Any) = nothing
_inspectdr_getmplot(r::InspecDRPlotRef) = r.mplot
function _initialize_backend(::InspectDRBackend; kw...)
@eval begin
import InspectDR
export InspectDR
_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)
#Glyph used when plotting "Shape"s:
INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y
)
mutable struct InspecDRPlotRef
mplot::Union{Nothing, InspectDR.Multiplot}
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
# ---------------------------------------------------------------------------
+22 -1
View File
@@ -2,6 +2,10 @@
# 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([
:annotations,
:background_color_legend,
@@ -43,6 +47,23 @@ const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :d
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(
@@ -103,7 +124,7 @@ function pgf_framestyle(style::Symbol)
return style
else
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
end
end
+42 -29
View File
@@ -1,6 +1,10 @@
# 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([
:annotations,
:background_color_legend, :background_color_inside, :background_color_outside,
@@ -64,7 +68,7 @@ function _plotly_framestyle(style::Symbol)
return style
else
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
end
end
@@ -72,37 +76,46 @@ 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_remote = "https://cdn.plot.ly/plotly-latest.min.js"
_js_code = open(read, _plotly_js_path, "r")
function _initialize_backend(::PlotlyBackend; kw...)
@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
_js_script = """
<script type='text/javascript'>
define('plotly', function(require, exports, module) {
$(_js_code)
});
require(['plotly'], function(Plotly) {
window.Plotly = Plotly;
});
</script>
"""
# borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2
_js_script = """
<script type='text/javascript'>
define('plotly', function(require, exports, module) {
$(_js_code)
});
require(['plotly'], function(Plotly) {
window.Plotly = Plotly;
});
</script>
"""
# if we're in IJulia call setupnotebook to load js and css
if isijulia()
display("text/html", _js_script)
# if we're in IJulia call setupnotebook to load js and css
if isijulia()
display("text/html", _js_script)
end
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
end
# TODO: other initialization
end
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
using UUIDs
push!(_initialized_backends, :plotly)
# ----------------------------------------------------------------
@@ -618,7 +631,7 @@ function plotly_series(plt::Plot, series::Series)
d_out[:hoverinfo] = "label+percent+name"
else
@warn("Plotly: seriestype $st isn't supported.")
warn("Plotly: seriestype $st isn't supported.")
return KW()
end
@@ -645,7 +658,7 @@ end
function plotly_series_shapes(plt::Plot, series::Series)
segments = iter_segments(series)
d_outs = Vector{KW}(undef, length(segments))
d_outs = Vector{KW}(length(segments))
# TODO: create a d_out for each polygon
# x, y = series[:x], series[:y]
@@ -707,7 +720,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}(undef, (hasfillrange ? 2 : 1 ) * length(segments))
d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments))
for (i,rng) in enumerate(segments)
!isscatter && length(rng) < 2 && continue
@@ -731,7 +744,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
d_out[:fill] = "tonexty"
d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i)))
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
d_out[:x], d_out[:y] = x[rng], y[rng]
@@ -893,7 +906,7 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing)
w, h = plt[:size]
style = "width:$(w)px;height:$(h)px;"
end
uuid = UUIDs.uuid4()
uuid = Base.Random.uuid4()
html = """
<div id=\"$(uuid)\" style=\"$(style)\"></div>
<script>
+33 -1
View File
@@ -1,3 +1,6 @@
@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
@@ -10,6 +13,35 @@ 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})
if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot)
PlotlyJS.SyncPlot(PlotlyJS.Plot(), current().o.view)
@@ -38,7 +70,7 @@ function _series_updated(plt::Plot{PlotlyJSBackend}, series::Series)
end
PlotlyJS.restyle!(
plt.o,
findfirst(isequal(series), plt.series_list),
findfirst(plt.series_list, series),
kw
)
end
+93 -69
View File
@@ -1,6 +1,10 @@
# 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([
:annotations,
:background_color_legend, :background_color_inside, :background_color_outside,
@@ -55,31 +59,57 @@ is_marker_supported(::PyPlotBackend, shape::Shape) = true
# --------------------------------------------------------------------------------------
# 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))
append!(Base.Multimedia.displays, otherdisplays)
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
function add_backend_string(::PyPlotBackend)
"""
if !Plots.is_installed("PyPlot")
Pkg.add("PyPlot")
end
withenv("PYTHON" => "") do
Pkg.build("PyPlot")
end
# "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
else
:set_facecolor
# now restart julia!
"""
end
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
else
:set_facecolor
end
# we don't want every command to update the figure
PyPlot.ioff()
end
end
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# # convert colorant to 4-tuple RGBA
# py_color(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (red, green, blue, alpha))
@@ -130,7 +160,7 @@ function py_linestyle(seriestype::Symbol, linestyle::Symbol)
linestyle == :dash && return "--"
linestyle == :dot && return ":"
linestyle == :dashdot && return "-."
@warn("Unknown linestyle $linestyle")
warn("Unknown linestyle $linestyle")
return "-"
end
@@ -191,13 +221,13 @@ function py_marker(marker::Symbol)
marker == :vline && return "|"
haskey(_shapes, marker) && return py_marker(_shapes[marker])
@warn("Unknown marker $marker")
warn("Unknown marker $marker")
return "o"
end
# py_marker(markers::AVec) = map(py_marker, markers)
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])
end
@@ -249,12 +279,10 @@ function labelfunc(scale::Symbol, backend::PyPlotBackend)
end
end
@require PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" begin
function py_mask_nans(z)
# pynp["ma"][:masked_invalid](z)))
PyCall.pycall(pynp["ma"][:masked_invalid], Any, z)
# pynp["ma"][:masked_where](pynp["isnan"](z),z)
end
function py_mask_nans(z)
# pynp["ma"][:masked_invalid](z)))
PyCall.pycall(pynp["ma"][:masked_invalid], Any, z)
# pynp["ma"][:masked_where](pynp["isnan"](z),z)
end
# ---------------------------------------------------------------------------
@@ -366,8 +394,8 @@ function py_bbox_title(ax)
bb
end
function py_thickness_scale(plt::Plot{PyPlotBackend}, ptsz)
ptsz * plt[:thickness_scaling]
function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz)
ptsz
end
# ---------------------------------------------------------------------------
@@ -477,7 +505,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
# :label => series[:label],
# :zorder => plt.n,
# :cmap => py_linecolormap(series),
# :linewidths => py_thickness_scale(plt, get_linewidth.(series, 1:n)),
# :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)),
# :linestyle => py_linestyle(st, get_linestyle.(series)),
# :norm => pycolors["Normalize"](; extrakw...)
# )
@@ -502,7 +530,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = i == 1 ? series[:label] : "",
zorder = series[:series_plotindex],
color = py_color(get_linecolor(series, i), get_linealpha(series, i)),
linewidth = py_thickness_scale(plt, get_linewidth(series, i)),
linewidth = py_dpi_scale(plt, get_linewidth(series, i)),
linestyle = py_linestyle(st, get_linestyle(series, i)),
solid_capstyle = "round",
drawstyle = py_stepstyle(st)
@@ -514,7 +542,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
a = series[:arrow]
if a != nothing && !is3d(st) # TODO: handle 3d later
if typeof(a) != Arrow
@warn("Unexpected type for arrow: $(typeof(a))")
warn("Unexpected type for arrow: $(typeof(a))")
else
arrowprops = KW(
:arrowstyle => "simple,head_length=$(a.headlength),head_width=$(a.headwidth)",
@@ -522,7 +550,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:shrinkB => 0,
:edgecolor => py_linecolor(series),
:facecolor => py_linecolor(series),
:linewidth => py_thickness_scale(plt, get_linewidth(series)),
:linewidth => py_dpi_scale(plt, get_linewidth(series)),
:linestyle => py_linestyle(st, get_linestyle(series)),
)
add_arrows(x, y) do xyprev, xy
@@ -561,7 +589,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
x,y = xyargs
shapes = series[:markershape]
msc = py_markerstrokecolor(series)
lw = py_thickness_scale(plt, series[:markerstrokewidth])
lw = py_dpi_scale(plt, series[:markerstrokewidth])
for i=1:length(y)
extrakw[:c] = _cycle(markercolor, i)
@@ -569,7 +597,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = py_marker(_cycle(shapes,i)),
s = py_thickness_scale(plt, _cycle(series[:markersize],i) .^ 2),
s = py_dpi_scale(plt, _cycle(series[:markersize],i) .^ 2),
edgecolors = msc,
linewidths = lw,
extrakw...
@@ -582,9 +610,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = py_marker(series[:markershape]),
s = py_thickness_scale(plt, series[:markersize] .^ 2),
s = py_dpi_scale(plt, series[:markersize] .^ 2),
edgecolors = py_markerstrokecolor(series),
linewidths = py_thickness_scale(plt, series[:markerstrokewidth]),
linewidths = py_dpi_scale(plt, series[:markerstrokewidth]),
extrakw...
)
push!(handles, handle)
@@ -596,7 +624,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = series[:label],
zorder = series[:series_plotindex],
gridsize = series[:bins],
linewidths = py_thickness_scale(plt, series[:linewidth]),
linewidths = py_dpi_scale(plt, series[:linewidth]),
edgecolors = py_linecolor(series),
cmap = py_fillcolormap(series), # applies to the pcolorfast object
extrakw...
@@ -627,7 +655,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
handle = ax[:contour](x, y, z, levelargs...;
label = series[:label],
zorder = series[:series_plotindex],
linewidths = py_thickness_scale(plt, series[:linewidth]),
linewidths = py_dpi_scale(plt, series[:linewidth]),
linestyles = py_linestyle(st, series[:linestyle]),
extrakw...
)
@@ -669,7 +697,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
zorder = series[:series_plotindex],
rstride = series[:stride][1],
cstride = series[:stride][2],
linewidth = py_thickness_scale(plt, series[:linewidth]),
linewidth = py_dpi_scale(plt, series[:linewidth]),
edgecolor = py_linecolor(series),
extrakw...
)
@@ -700,7 +728,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
label = series[:label],
zorder = series[:series_plotindex],
cmap = py_fillcolormap(series),
linewidth = py_thickness_scale(plt, series[:linewidth]),
linewidth = py_dpi_scale(plt, series[:linewidth]),
edgecolor = py_linecolor(series),
extrakw...
)
@@ -768,7 +796,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
zorder = series[:series_plotindex],
edgecolor = py_color(get_linecolor(series, i), get_linealpha(series, i)),
facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)),
linewidth = py_thickness_scale(plt, get_linewidth(series, i)),
linewidth = py_dpi_scale(plt, get_linewidth(series, i)),
linestyle = py_linestyle(st, get_linestyle(series, i)),
fill = true
)
@@ -884,7 +912,7 @@ end
function py_set_scale(ax, axis::Axis)
scale = axis[:scale]
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")]
kw = KW()
arg = if scale == :identity
@@ -927,8 +955,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
w, h = plt[:size]
fig = plt.o
fig[:clear]()
dpi = plt[:dpi]
fig[:set_size_inches](w/DPI, h/DPI, forward = true)
dpi = plt[:thickness_scaling] * plt[:dpi]
fig[:set_size_inches](w/DPI/plt[:thickness_scaling], h/DPI/plt[:thickness_scaling], forward = true)
fig[set_facecolor_sym](py_color(plt[:background_color_outside]))
fig[:set_dpi](plt[:dpi])
@@ -968,7 +996,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
:title
end
ax[func][:set_text](sp[:title])
ax[func][:set_fontsize](py_thickness_scale(plt, sp[:titlefontsize]))
ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefontsize]))
ax[func][:set_family](sp[:titlefontfamily])
ax[func][:set_color](py_color(sp[:titlefontcolor]))
# ax[:set_title](sp[:title], loc = loc)
@@ -1008,9 +1036,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
fig = plt.o
cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym()))
cb = fig[:colorbar](handle; cax = cbax, kw...)
cb[:set_label](sp[:colorbar_title],size=py_thickness_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor]))
cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor]))
for lab in cb[:ax][:yaxis][:get_ticklabels]()
lab[:set_fontsize](py_thickness_scale(plt, sp[:yaxis][:tickfontsize]))
lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfontsize]))
lab[:set_family](sp[:yaxis][:tickfontfamily])
lab[:set_color](py_color(sp[:yaxis][:tickfontcolor]))
end
@@ -1020,14 +1048,12 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# framestyle
if !ispolar(sp) && !is3d(sp)
ax[:spines]["left"][:set_linewidth](py_thickness_scale(plt, 1))
ax[:spines]["bottom"][:set_linewidth](py_thickness_scale(plt, 1))
if sp[:framestyle] == :semi
intensity = 0.5
ax[:spines]["right"][:set_alpha](intensity)
ax[:spines]["top"][:set_alpha](intensity)
ax[:spines]["right"][:set_linewidth](py_thickness_scale(plt, intensity))
ax[:spines]["top"][:set_linewidth](py_thickness_scale(plt, intensity))
ax[:spines]["right"][:set_linewidth](intensity)
ax[:spines]["top"][:set_linewidth](intensity)
elseif sp[:framestyle] in (:axes, :origin)
ax[:spines]["right"][:set_visible](false)
ax[:spines]["top"][:set_visible](false)
@@ -1040,8 +1066,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
spine[:set_visible](false)
end
if sp[:framestyle] == :zerolines
ax[:axhline](y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
ax[:axvline](x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
ax[:axhline](y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = 0.75)
ax[:axvline](x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = 0.75)
end
end
end
@@ -1074,10 +1100,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
if get(axis.d, :flip, false)
ax[Symbol("invert_", letter, "axis")]()
end
pyaxis[:label][:set_fontsize](py_thickness_scale(plt, axis[:guidefontsize]))
pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefontsize]))
pyaxis[:label][:set_family](axis[:guidefontfamily])
for lab in ax[Symbol("get_", letter, "ticklabels")]()
lab[:set_fontsize](py_thickness_scale(plt, axis[:tickfontsize]))
lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfontsize]))
lab[:set_family](axis[:tickfontfamily])
lab[:set_rotation](axis[:rotation])
end
@@ -1086,7 +1112,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
pyaxis[:grid](true,
color = fgcolor,
linestyle = py_linestyle(:line, axis[:gridstyle]),
linewidth = py_thickness_scale(plt, axis[:gridlinewidth]),
linewidth = axis[:gridlinewidth],
alpha = axis[:gridalpha])
ax[:set_axisbelow](true)
else
@@ -1183,7 +1209,7 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend})
rightpad += sp[:right_margin]
bottompad += sp[:bottom_margin]
dpi_factor = Plots.DPI / sp.plt[:dpi]
dpi_factor = sp.plt[:thickness_scaling] * Plots.DPI / sp.plt[:dpi]
sp.minpad = Tuple(dpi_factor .* [leftpad, toppad, rightpad, bottompad])
end
@@ -1206,7 +1232,7 @@ function py_add_annotations(sp::Subplot{PyPlotBackend}, x, y, val::PlotText)
horizontalalignment = val.font.halign == :hcenter ? "center" : string(val.font.halign),
verticalalignment = val.font.valign == :vcenter ? "center" : string(val.font.valign),
rotation = val.font.rotation * 180 / π,
size = py_thickness_scale(sp.plt, val.font.pointsize),
size = py_dpi_scale(sp.plt, val.font.pointsize),
zorder = 999
)
end
@@ -1237,13 +1263,13 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
pypatches[:Patch](
edgecolor = py_color(get_linecolor(series), get_linealpha(series)),
facecolor = py_color(get_fillcolor(series), get_fillalpha(series)),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(series[:seriestype], get_linestyle(series))
)
elseif series[:seriestype] in (:path, :straightline)
PyPlot.plt[:Line2D]((0,1),(0,0),
color = py_color(get_linecolor(series), get_linealpha(series)),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(:path, get_linestyle(series)),
marker = py_marker(series[:markershape]),
markeredgecolor = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)),
@@ -1262,13 +1288,11 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
labels,
loc = get(_pyplot_legend_pos, leg, "best"),
scatterpoints = 1,
fontsize = py_thickness_scale(plt, sp[:legendfontsize]),
fontsize = py_dpi_scale(plt, sp[:legendfontsize]),
facecolor = py_color(sp[:background_color_legend]),
edgecolor = py_color(sp[:foreground_color_legend]),
framealpha = alpha(plot_color(sp[:background_color_legend])),
)
frame = leg[:get_frame]()
frame[:set_linewidth](py_thickness_scale(plt, 1))
leg[:set_zorder](1000)
sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle])
@@ -1336,7 +1360,7 @@ for (mime, fmt) in _pyplot_mimeformats
# figsize = map(px2inch, plt[:size]),
facecolor = fig[:get_facecolor](),
edgecolor = "none",
dpi = plt[:dpi]
dpi = plt[:dpi] * plt[:thickness_scaling]
)
end
end
+8 -3
View File
@@ -3,9 +3,14 @@
# [ADD BACKEND WEBSITE]
import [PkgName]
export [PkgName]
push!(_initialized_backends, [pgkname]::Symbol)
function _initialize_backend(::[PkgName]Backend; kw...)
@eval begin
import [PkgName]
export [PkgName]
# todo: other initialization that needs to be eval-ed
end
# todo: other initialization
end
# ---------------------------------------------------------------------------
+20
View File
@@ -1,6 +1,10 @@
# 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([
:label,
:legend,
@@ -29,6 +33,22 @@ 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)
function _canvas_map()
+3
View File
@@ -2,6 +2,9 @@
# NOTE: backend should implement `html_body` and `html_head`
# 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"))
"""
+9 -12
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))
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))
compute_angle(v::P2) = (angle = atan(v[2], v[1]); angle < 0 ? 2π - angle : angle)
compute_angle(v::P2) = (angle = atan2(v[2], v[1]); angle < 0 ? 2π - angle : angle)
# -------------------------------------------------------------
@@ -297,7 +297,7 @@ function font(args...)
elseif typeof(arg) <: Real
rotation = convert(Float64, arg)
else
@warn("Unused font arg: $arg ($(typeof(arg)))")
warn("Unused font arg: $arg ($(typeof(arg)))")
end
end
@@ -396,7 +396,7 @@ function stroke(args...; alpha = nothing)
elseif allReals(arg)
width = arg
else
@warn("Unused stroke arg: $arg ($(typeof(arg)))")
warn("Unused stroke arg: $arg ($(typeof(arg)))")
end
end
@@ -429,7 +429,7 @@ function brush(args...; alpha = nothing)
elseif allReals(arg)
size = arg
else
@warn("Unused brush arg: $arg ($(typeof(arg)))")
warn("Unused brush arg: $arg ($(typeof(arg)))")
end
end
@@ -460,7 +460,7 @@ function series_annotations(strs::AbstractVector, args...)
elseif is_2tuple(arg)
scalefactor = arg
else
@warn("Unused SeriesAnnotations arg: $arg ($(typeof(arg)))")
warn("Unused SeriesAnnotations arg: $arg ($(typeof(arg)))")
end
end
# if scalefactor != 1
@@ -523,12 +523,9 @@ mutable struct EachAnn
x
y
end
function Base.iterate(ea::EachAnn, i = 1)
if ea.anns == nothing || isempty(ea.anns.strs) || i > length(ea.y)
return nothing
end
Base.start(ea::EachAnn) = 1
Base.done(ea::EachAnn, i) = ea.anns == nothing || isempty(ea.anns.strs) || i > length(ea.y)
function Base.next(ea::EachAnn, i)
tmp = _cycle(ea.anns.strs,i)
str,fnt = if isa(tmp, PlotText)
tmp.str, tmp.font
@@ -704,7 +701,7 @@ function arrow(args...)
elseif T <: Tuple && length(arg) == 2
headlength, headwidth = Float64(arg[1]), Float64(arg[2])
else
@warn("Skipped arrow arg $arg")
warn("Skipped arrow arg $arg")
end
end
Arrow(style, side, headlength, headwidth)
+1 -1
View File
@@ -197,7 +197,7 @@ function getGadflyMarkerTheme(d::KW, attr::KW)
ms = d[:markersize]
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
else
ms * Gadfly.px
+2 -2
View File
@@ -150,7 +150,7 @@ function updateLimsAndTicks(plt::Plot{QwtBackend}, d::KW, isx::Bool)
end
w[:setAxisScale](axisid, float(minimum(ticks)), float(maximum(ticks)), float(step(ticks)))
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
# 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 == :log2 && w[:setAxisScaleEngine](axisid, Qwt.QWT.QwtLogScaleEngine(2))
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
+2 -2
View File
@@ -120,7 +120,7 @@ struct ColorGradient <: ColorScheme
# # otherwise interpolate evenly between the minval and maxval
# minval, maxval = minimum(vals), maximum(vals)
# vs = Float64[interpolate(minval, maxval, w) for w in range(0, stop = 1, length = length(cs))]
# vs = Float64[interpolate(minval, maxval, w) for w in linspace(0, 1, length(cs))]
# new(convertColor(cs,alpha), vs)
# interpolate the colors for each value
@@ -147,7 +147,7 @@ function ColorGradient(s::Symbol, vals::AVec{T} = 0:0; kw...) where T<:Real
ColorGradient(cs, vals; kw...)
end
# function ColorGradient{T<:Real}(cs::AVec, vals::AVec{T} = range(0, stop = 1, length = length(cs)); kw...)
# function ColorGradient{T<:Real}(cs::AVec, vals::AVec{T} = linspace(0, 1, length(cs)); kw...)
# ColorGradient(map(convertColor, cs), vals; kw...)
# end
-70
View File
@@ -1,70 +0,0 @@
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", "glvisualize.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
+3 -3
View File
@@ -5,8 +5,8 @@ to_pixels(m::AbsoluteLength) = m.value / 0.254
const _cbar_width = 5mm
#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::Measure, n::Number) = m * n
Base.broadcast(::typeof(Base.:.*), m::Number, n::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
@@ -147,7 +147,7 @@ function bbox(x, y, w, h, oarg1::Symbol, originargs::Symbol...)
elseif oarg in (:top, :bottom, :vcenter)
origver = oarg
else
@warn("Unused origin arg in bbox construction: $oarg")
warn("Unused origin arg in bbox construction: $oarg")
end
end
bbox(x, y, w, h; h_anchor = orighor, v_anchor = origver)
+106 -24
View File
@@ -173,10 +173,10 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
end
if output_type == :png
# @info("writing png to html output")
# info("writing png to html output")
print(io, "<img src=\"data:image/png;base64,", base64encode(show, MIME("image/png"), plt), "\" />")
elseif output_type == :svg
# @info("writing svg to html output")
# info("writing svg to html output")
show(io, MIME("image/svg+xml"), plt)
elseif output_type == :txt
show(io, MIME("text/plain"), plt)
@@ -185,8 +185,8 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
end
# delegate showable to _show instead
function Base.showable(m::M, plt::P) where {M<:MIME, P<:Plot}
# delegate mimewritable (showable on julia 0.7) to _show instead
function Base.mimewritable(m::M, plt::P) where {M<:MIME, P<:Plot}
return hasmethod(_show, Tuple{IO, M, P})
end
@@ -199,12 +199,8 @@ for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml
"application/eps", "application/pdf", "application/postscript",
"application/x-tex")
@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)
_show(io, m, plt)
end
prepare_output(plt)
_show(io, m, plt)
end
end
@@ -255,26 +251,112 @@ end
#
# 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
# ---------------------------------------------------------
function showjuno(io::IO, m, plt)
sz = plt[:size]
dpi = plt[:dpi]
thickness_scaling = plt[:thickness_scaling]
@require Juno = "e5e0dc1b-0480-54bc-9374-aad01c23163d" begin
import Hiccup, Media
jsize = get(io, :juno_plotsize, [400, 500])
if Juno.isactive()
Media.media(Plot, Media.Plot)
scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = (s * scale for s in sz)
plt[:dpi] = Plots.DPI
plt[:thickness_scaling] *= scale
function Juno.render(e::Juno.Editor, plt::Plot)
Juno.render(e, nothing)
end
prepare_output(plt)
_show(io, m, plt)
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]
dpi = plt[:dpi]
thickness_scaling = plt[:thickness_scaling]
jsize = Juno.plotsize()
jsize[1] == 0 && (jsize[1] = 400)
jsize[2] == 0 && (jsize[2] = 500)
plt[:size] = sz
plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling
scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = (s * scale for s in sz)
plt[:dpi] = Plots.DPI
plt[:thickness_scaling] *= scale
Juno.render(pane, HTML(stringmime(MIME("text/html"), plt)))
plt[:size] = sz
plt[:dpi] = dpi
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
+1 -1
View File
@@ -416,7 +416,7 @@ function _process_seriesrecipe(plt::Plot, d::KW)
end
_process_seriesrecipe(plt, data.d)
else
@warn("Unhandled recipe: $(data)")
warn("Unhandled recipe: $(data)")
break
end
end
+5 -5
View File
@@ -177,7 +177,7 @@ function _plot!(plt::Plot, d::KW, args::Tuple)
kw_list = _process_userrecipes(plt, d, args)
# @info(1)
# info(1)
# map(DD, kw_list)
@@ -196,7 +196,7 @@ function _plot!(plt::Plot, d::KW, args::Tuple)
_process_plotrecipe(plt, next_kw, kw_list, still_to_process)
end
# @info(2)
# info(2)
# map(DD, kw_list)
# --------------------------------
@@ -212,7 +212,7 @@ function _plot!(plt::Plot, d::KW, args::Tuple)
# "SERIES RECIPES"
# --------------------------------
# @info(3)
# info(3)
# map(DD, kw_list)
for kw in kw_list
@@ -283,11 +283,11 @@ end
function plot(sp::Subplot, args...; kw...)
plt = sp.plt
plot(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
plot(plt, args...; kw..., subplot = findfirst(plt.subplots, sp))
end
function plot!(sp::Subplot, args...; kw...)
plt = sp.plt
plot!(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
plot!(plt, args...; kw..., subplot = findfirst(plt.subplots, sp))
end
# --------------------------------------------------------------------
+1 -1
View File
@@ -46,7 +46,7 @@ function plotattr(attrtype::Symbol, attribute::AbstractString)
attribute = Symbol(lookup_aliases(attrtype, attribute))
desc = get(_arg_desc, attribute, "")
first_period_idx = findfirst(isequal('.'), desc)
first_period_idx = findfirst(desc, '.')
typedesc = desc[1:first_period_idx-1]
desc = strip(desc[first_period_idx+1:end])
als = keys(filter((_,v)->v==attribute, _keyAliases)) |> collect |> sort
+11 -18
View File
@@ -284,7 +284,7 @@ end
# where the points are the control points of the curve
for rng in iter_segments(args...)
length(rng) < 2 && continue
ts = range(0, stop = 1, length = npoints)
ts = linspace(0, 1, npoints)
nanappend!(newx, map(t -> bezier_value(_cycle(x,rng), t), ts))
nanappend!(newy, map(t -> bezier_value(_cycle(y,rng), t), ts))
if z != nothing
@@ -498,25 +498,21 @@ function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::S
log_scale_x = xscale in _logScales
log_scale_y = yscale in _logScales
nbins = length(eachindex(weights))
if length(eachindex(edge)) != nbins + 1
nbins = length(linearindices(weights))
if length(linearindices(edge)) != nbins + 1
error("Edge vector must be 1 longer than weight vector")
end
x = eltype(edge)[]
y = eltype(weights)[]
it_tuple_e = iterate(edge)
a, it_state_e = it_tuple_e
it_tuple_e = iterate(edge, it_state_e)
it_tuple_w = iterate(weights)
it_e, it_w = start(edge), start(weights)
a, it_e = next(edge, it_e)
last_w = eltype(weights)(NaN)
while it_tuple_e != nothing && it_tuple_w != nothing
b, it_state_e = it_tuple_e
w, it_state_w = it_tuple_w
i = 1
while (!done(edge, it_e) && !done(edge, it_e))
b, it_e = next(edge, it_e)
w, it_w = next(weights, it_w)
if (log_scale_x && a 0)
a = b/_logScaleBases[xscale]^3
@@ -540,9 +536,6 @@ function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::S
a = b
last_w = w
it_tuple_e = iterate(edge, it_state_e)
it_tuple_w = iterate(weights, it_state_w)
end
if (last_w != baseline)
push!(x, a)
@@ -586,7 +579,7 @@ end
end
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
_cl(x) = ceil(Int, NaNMath.max(x, one(x)))
@@ -626,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::AbstractVector) where {N} = binning
_hist_edges(vs::NTuple{N,AbstractVector}, binning::NTuple{N, Any}) where {N} =
_hist_edges(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) where {N} =
map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...,))
_hist_edges(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, AbstractVector}) where {N} =
+2 -2
View File
@@ -518,7 +518,7 @@ end
xs, fs
end
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, u::AVec) where {F<:Function,G<:Function} = mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u)
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, umin::Number, umax::Number, n = 200) where {F<:Function,G<:Function} = fx, fy, range(umin, stop = umax, length = n)
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, umin::Number, umax::Number, n = 200) where {F<:Function,G<:Function} = fx, fy, linspace(umin, umax, n)
#
# # special handling... 3D parametric function(s)
@@ -526,7 +526,7 @@ end
mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u)
end
@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, umin::Number, umax::Number, numPoints = 200) where {F<:Function,G<:Function,H<:Function}
fx, fy, fz, range(umin, stop = umax, length = numPoints)
fx, fy, fz, linspace(umin, umax, numPoints)
end
#
+3 -3
View File
@@ -10,7 +10,7 @@ end
function _get_defaults(s::Symbol)
thm = PlotThemes._themes[s]
if :defaults in fieldnames(typeof(thm))
if :defaults in fieldnames(thm)
return thm.defaults
else # old PlotTheme type
defaults = KW(
@@ -132,7 +132,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
f(r) = sin(r) / r
_norm(x, y) = norm([x, y])
x = y = range(-3π, stop = 3π, length = 30)
x = y = linspace(-3π, 3π, 30)
z = f.(_norm.(x, y'))
wi = 2:3:30
@@ -152,7 +152,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
end
n = 100
ts = range(0, stop = 10π, length = n)
ts = linspace(0, 10π, n)
x = ts .* cos.(ts)
y = (0.1ts) .* sin.(ts)
z = 1:n
+2 -3
View File
@@ -5,7 +5,6 @@
const AVec = AbstractVector
const AMat = AbstractMatrix
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
@@ -88,7 +87,7 @@ end
Base.getindex(plt::Plot, i::Integer) = plt.subplots[i]
Base.length(plt::Plot) = length(plt.subplots)
Base.lastindex(plt::Plot) = length(plt)
Base.endof(plt::Plot) = length(plt)
Base.getindex(plt::Plot, r::Integer, c::Integer) = plt.layout[r,c]
Base.size(plt::Plot) = size(plt.layout)
@@ -99,6 +98,6 @@ Base.ndims(plt::Plot) = 2
# attr!(plt::Plot, v, k::Symbol) = (plt.attr[k] = v)
Base.getindex(sp::Subplot, i::Integer) = series_list(sp)[i]
Base.lastindex(sp::Subplot) = length(series_list(sp))
Base.endof(sp::Subplot) = length(series_list(sp))
# -----------------------------------------------------------------------
+13 -10
View File
@@ -215,12 +215,15 @@ 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)
allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend)
function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1)
nextidx > itr.n && return nothing
if nextidx == 1 && !any(isempty,itr.args) && anynan(1, itr.args)
nextidx = 2
function Base.start(itr::SegmentsIterator)
nextidx = 1
if !any(isempty,itr.args) && anynan(1, itr.args)
_, nextidx = next(itr, 1)
end
nextidx
end
Base.done(itr::SegmentsIterator, nextidx::Int) = nextidx > itr.n
function Base.next(itr::SegmentsIterator, nextidx::Int)
i = istart = iend = nextidx
# find the next NaN, and iend is the one before
@@ -303,7 +306,7 @@ function _expand_limits(lims, x)
lims[1] = NaNMath.min(lims[1], e1)
lims[2] = NaNMath.max(lims[2], e2)
# catch err
# @warn(err)
# warn(err)
catch
end
nothing
@@ -409,8 +412,8 @@ function fakedata(sz...)
y
end
isijulia() = :IJulia in nameof.(collect(values(Base.loaded_modules)))
isatom() = :Atom in nameof.(collect(values(Base.loaded_modules)))
isijulia() = isdefined(Main, :IJulia) && Main.IJulia.inited
isatom() = isdefined(Main, :Atom) && Main.Atom.isconnected()
function is_installed(pkgstr::AbstractString)
try
@@ -930,7 +933,7 @@ function attr!(series::Series; kw...)
if haskey(_series_defaults, k)
series[k] = v
else
@warn("unused key $k in series attr")
warn("unused key $k in series attr")
end
end
_series_updated(series[:subplot].plt, series)
@@ -944,7 +947,7 @@ function attr!(sp::Subplot; kw...)
if haskey(_subplot_defaults, k)
sp[k] = v
else
@warn("unused key $k in subplot attr")
warn("unused key $k in subplot attr")
end
end
sp
-1
View File
@@ -6,4 +6,3 @@ GR 0.31.0
RDatasets
VisualRegressionTests
UnicodePlots
LaTeXStrings
+4 -4
View File
@@ -9,7 +9,7 @@ using VisualRegressionTests
# ENV["MPLBACKEND"] = "Agg"
# try
# @eval import PyPlot
# @info("Matplotlib version: $(PyPlot.matplotlib[:__version__])")
# info("Matplotlib version: $(PyPlot.matplotlib[:__version__])")
# end
@@ -23,18 +23,18 @@ 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.17.4"
const _current_plots_version = v"0.17.3"
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
Plots._debugMode.on = debug
example = Plots._examples[idx]
@info("Testing plot: $pkg:$idx:$(example.header)")
info("Testing plot: $pkg:$idx:$(example.header)")
backend(pkg)
backend()
# ensure consistent results
Random.seed!(1234)
srand(1234)
# reference image directory setup
# refdir = joinpath(Pkg.dir("ExamplePlots"), "test", "refimg", string(pkg))
+1 -1
View File
@@ -3,7 +3,7 @@ module PlotsTests
include("imgcomp.jl")
# don't actually show the plots
Random.seed!(1234)
srand(1234)
default(show=false, reuse=true)
img_eps = isinteractive() ? 1e-2 : 10e-2