diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 236bcb9a..f056031a 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -20,10 +20,11 @@ Backend | yes | no | untested -------------|-----|-----|--------- gr (default) | | | pyplot | | | -plotly | | | plotlyjs | | | pgfplotsx | | | +unicodeplots | | | inspectdr | | | +gaston | | | ### Versions diff --git a/.zenodo.json b/.zenodo.json index 029e9329..439b6334 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -692,6 +692,16 @@ { "name": "Fred Callaway", "type": "Other" + }, + { + "name": "Jan Thorben Schneider", + "type": "Other" + }, + { + "orcid": "0000-0003-4102-2460", + "affiliation": "Alogus Research Corporation:, + "name": "Lee Phillips", + "type": "Other" } ], "upload_type": "software" diff --git a/Project.toml b/Project.toml index 599eb780..b6491d66 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Plots" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" author = ["Tom Breloff (@tbreloff)"] -version = "1.22.1" +version = "1.22.3" [deps] Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" diff --git a/README.md b/README.md index a097683e..2b13d13a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [gitter-url]: https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge [docs-img]: https://img.shields.io/badge/docs-stable-blue.svg -[docs-url]: http://docs.juliaplots.org/latest/ +[docs-url]: https://docs.juliaplots.org/latest/ [![][gh-ci-img]][gh-ci-url] [![][pkgeval-img]][pkgeval-url] diff --git a/deps/SnoopCompile/precompile/precompile_Plots.jl b/deps/SnoopCompile/precompile/precompile_Plots.jl index b2e31fb8..3482ca03 100644 --- a/deps/SnoopCompile/precompile/precompile_Plots.jl +++ b/deps/SnoopCompile/precompile/precompile_Plots.jl @@ -76,20 +76,28 @@ function _precompile_() Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Tuple{Int64, Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol}) Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,), Tuple{Bool}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{Symbol}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :flip, :minorgrid, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Float64, Float64}}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Float64, Float64}, Bool}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :guide), Tuple{Bool, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :mirror, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid,), Tuple{Bool}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid), Tuple{Int64, Bool, Float64, Symbol, RGBA{Float64}}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide,), Tuple{String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide_position, :guidefontvalign, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guidefonthalign, :guide_position, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, StepRange{Int64, Int64}, String}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Float64, Float64}}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid, :scale, :guide), Tuple{Bool, Symbol, String}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid,), Tuple{Bool}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:rotation,), Tuple{Int64}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{Nothing}},typeof(attr!),Axis}) + Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{UnitRange{Int64}}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:shape,), Tuple{Symbol}},typeof(default)}) Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:titlefont, :legendfontsize, :guidefont, :tickfont, :guide, :framestyle, :yminorgrid), Tuple{Tuple{Int64, String}, Int64, Tuple{Int64, Symbol}, Tuple{Int64, Symbol}, String, Symbol, Bool}},typeof(default)}) Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :halign, :valign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)}) @@ -117,6 +125,8 @@ function _precompile_() Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Float64}}) @@ -130,11 +140,13 @@ function _precompile_() Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vector{Float64},Vararg{Any, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{GRBackend}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{PlotlyBackend}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!)}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg), Tuple{Tuple{Int64, Float64, PlotText}, Bool}},typeof(plot),Vector{Float64}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:arrow,), Tuple{Int64}},typeof(plot),Vector{Float64},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype), Tuple{Symbol, Vector{Int64}, Symbol}},typeof(plot),Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker), Tuple{Matrix{Symbol}, Tuple{Symbol, Int64}, Tuple{Matrix{Symbol}, Int64, Float64, Stroke}}},typeof(plot),Vector{Vector{T} where T}}) @@ -145,6 +157,7 @@ function _precompile_() Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α), Tuple{String, Int64, PlotUtils.ContinuousColorGradient, Int64, Float64}},typeof(plot),StepRange{Int64, Int64},Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Float64}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label,), Tuple{Matrix{String}}},typeof(plot),Vector{AbstractVector{Float64}}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:labels,), Tuple{Matrix{String}}},typeof(plot),PortfolioComposition}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor), Tuple{GridLayout, Vector{String}, Matrix{Symbol}, Symbol}},typeof(plot),Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}}) @@ -179,12 +192,14 @@ function _precompile_() Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:projection, :seriestype), Tuple{Symbol, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},UnitRange{Int64},Matrix{Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype), Tuple{Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:reg, :fill), Tuple{Bool, Tuple{Int64, Symbol}}},typeof(plot),Vector{Float64}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Int64}},typeof(plot),UnitRange{Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}},typeof(plot),UnitRange{Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64}, LinRange{Float64}}}},typeof(plot),UnitRange{Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}}) + Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}}) @@ -203,6 +218,7 @@ function _precompile_() Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64, N} where N}) Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{OHLC}}) Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},PortfolioComposition}) + Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barbins}},Any,Any,Any}) Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barhist}},Any,Any,Any}) Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bar}},Any,Any,Any}) Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bins2d}},Any,Any,Any}) @@ -221,6 +237,7 @@ function _precompile_() Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}}) Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}}) Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict}) + Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_axis_args!),Plot{PlotlyBackend},Dict{Symbol, Any},Symbol}) Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}}) Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}}) Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},DefaultsDict,Symbol,Any}) @@ -233,7 +250,10 @@ function _precompile_() Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},String}) Base.precompile(Tuple{typeof(_cbar_unique),Vector{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}},String}) Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String}) - Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}}) + Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}}) + Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}}) + Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}}) + Base.precompile(Tuple{typeof(_cycle),Vector{Float64},Vector{Int64}}) Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool}) Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool}) Base.precompile(Tuple{typeof(_heatmap_edges),Vector{Float64},Bool,Bool}) @@ -253,45 +273,39 @@ function _precompile_() Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}}) Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Int64, Float64}}) Base.precompile(Tuple{typeof(create_grid),Expr}) - Base.precompile(Tuple{typeof(default),Symbol,String}) Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N}) Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}}) Base.precompile(Tuple{typeof(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}}) - Base.precompile(Tuple{typeof(expand_extrema!),Axis,UnitRange{Int64}}) Base.precompile(Tuple{typeof(fakedata),Int64,Int64}) + Base.precompile(Tuple{typeof(get_clims),Subplot{GRBackend},Series,Function}) Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}}) Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}}) - Base.precompile(Tuple{typeof(get_series_color),PlotUtils.ContinuousColorGradient,Subplot{GRBackend},Int64,Symbol}) + Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol}) + Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},Int64,Symbol}) Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N}) Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N}) Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any, N} where N}) Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N}) Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N}) - Base.precompile(Tuple{typeof(get_xy),OHLC{Float64},Int64,Float64}) Base.precompile(Tuple{typeof(get_xy),Vector{OHLC}}) Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}}) Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}}) Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},AbsoluteLength,AbsoluteLength,Vector{Float64}}) - Base.precompile(Tuple{typeof(gr_draw_colorbar),GRColorbar,Subplot{GRBackend},Tuple{Float64, Float64},Vector{Float64}}) Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64},Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol}) Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol}) Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol}) - Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}}) - Base.precompile(Tuple{typeof(gr_draw_markers),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Float64, Float64}}) - Base.precompile(Tuple{typeof(gr_draw_markers),Series,UnitRange{Int64},Vector{Float64},Tuple{Float64, Float64}}) - Base.precompile(Tuple{typeof(gr_draw_markers),Series,Vector{Int64},Vector{Float64},Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Vector{Float64}, Vector{Float64}},Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}}) - Base.precompile(Tuple{typeof(gr_draw_shapes),Series,Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}}) Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}}) Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64}) + Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Int64}, Vector{String}},Int64}) Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}}) Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}}) Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}}) @@ -307,7 +321,7 @@ function _precompile_() Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol,Vector{Float64},Symbol,Tuple{Int64, Int64},Bool}) Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol}) Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}}) - Base.precompile(Tuple{typeof(intersection_point),Float64,Float64,Float64,Float64,Float64,Float64}) + Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64}}) Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Function}) Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Symbol}) Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Float64},Symbol,Symbol}) @@ -321,14 +335,15 @@ function _precompile_() Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}}) Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N}) Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}}) + Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Float64,Symbol}) Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol}) Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{Symbol}}) Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Symbol}) Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Matrix{Symbol}}) Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}}) Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape{Float64, Float64}}) + Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Stroke}) Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol}) - Base.precompile(Tuple{typeof(processMinorGridArg!),Dict{Symbol, Any},Bool,Symbol}) Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText}) Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}}) Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}}) @@ -337,11 +352,18 @@ function _precompile_() Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}}) Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol}) Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol}) - Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Tuple{Int64, Int64},Symbol}) Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}}) Base.precompile(Tuple{typeof(resetfontsizes)}) Base.precompile(Tuple{typeof(scalefontsizes),Float64}) Base.precompile(Tuple{typeof(series_annotations),Vector{Any}}) + Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{PlotUtils.ContinuousColorGradient},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{RGBA{Float64}},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{String},Int64}) + Base.precompile(Tuple{typeof(slice_arg),Matrix{Symbol},Int64}) Base.precompile(Tuple{typeof(spy),Any}) Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64, Float64},Tuple{Float64, Float64},Vector{Float64},Vector{Float64},Int64}) Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any, N} where N}) @@ -361,6 +383,11 @@ function _precompile_() precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(font),Font,Vararg{Any, N} where N,)) end end + let fbody = try __lookup_kwbody__(which(gr_polyline, (Vector{Float64},Vector{Float64},typeof(GR.fillarea),))) catch missing end + if !ismissing(fbody) + precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Vector{Float64},Vector{Float64},typeof(GR.fillarea),)) + end + end let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end if !ismissing(fbody) precompile(fbody, (Any,typeof(plot!),Any,)) @@ -386,9 +413,4 @@ function _precompile_() precompile(fbody, (Any,typeof(title!),AbstractString,)) end end - let fbody = try __lookup_kwbody__(which(vline!, (Any,))) catch missing end - if !ismissing(fbody) - precompile(fbody, (Any,typeof(vline!),Any,)) - end - end end diff --git a/src/args.jl b/src/args.jl index b45f9829..823f0bc5 100644 --- a/src/args.jl +++ b/src/args.jl @@ -848,7 +848,14 @@ add_axes_aliases(:ticks, :tick) add_axes_aliases(:rotation, :rot, :r) add_axes_aliases(:guidefontsize, :labelfontsize) add_axes_aliases(:gridalpha, :ga, :galpha, :gα, :gridopacity, :gopacity) -add_axes_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) +add_axes_aliases( + :gridstyle, + :grid_style, + :gridlinestyle, + :grid_linestyle, + :grid_ls, + :gridls, +) add_axes_aliases( :foreground_color_grid, :fg_grid, @@ -873,7 +880,14 @@ add_axes_aliases( :fg_colour_minor_grid, :minorgridcolor, ) -add_axes_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) +add_axes_aliases( + :gridlinewidth, + :gridwidth, + :grid_linewidth, + :grid_width, + :gridlw, + :grid_lw, +) add_axes_aliases( :minorgridstyle, :minorgrid_style, @@ -1570,7 +1584,8 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes) end end - if !isempty(_to_warn) && get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported]) + if !isempty(_to_warn) && + get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported]) for k in sort(collect(_to_warn)) push!(already_warned, k) @warn( diff --git a/src/backends.jl b/src/backends.jl index 7b1bc646..c9e65aa5 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -402,6 +402,7 @@ const _gr_attr = merge_with_base_supported([ :tick_direction, :camera, :contour_labels, + :connections, ]) const _gr_seriestype = [ :path, @@ -521,6 +522,7 @@ const _plotly_attr = merge_with_base_supported([ :tick_direction, :camera, :contour_labels, + :connections, ]) const _plotly_seriestype = [ @@ -777,6 +779,7 @@ const _pyplot_attr = merge_with_base_supported([ :tick_direction, :camera, :contour_labels, + :connections, ]) const _pyplot_seriestype = [ :path, @@ -793,6 +796,7 @@ const _pyplot_seriestype = [ :contour3d, :path3d, :scatter3d, + :mesh3d, :surface, :wireframe, ] @@ -860,6 +864,7 @@ const _gaston_attr = merge_with_base_supported([ # :framestyle, # :camera, # :contour_labels, + :connections, ]) const _gaston_seriestype = [ @@ -938,7 +943,34 @@ const _unicodeplots_seriestype = [ :spy, ] const _unicodeplots_style = [:auto, :solid] -const _unicodeplots_marker = [:none, :auto, :circle] +const _unicodeplots_marker = [ + :none, + :auto, + :pixel, + # vvvvvvvvvv shapes + :circle, + :rect, + :star5, + :diamond, + :hexagon, + :cross, + :xcross, + :utriangle, + :dtriangle, + :rtriangle, + :ltriangle, + :pentagon, + # :heptagon, + # :octagon, + :star4, + :star6, + # :star7, + :star8, + :vline, + :hline, + :+, + :x, +] const _unicodeplots_scale = [:identity, :ln, :log2, :log10] # Additional constants @@ -1240,6 +1272,7 @@ const _pgfplotsx_attr = merge_with_base_supported([ :tick_direction, :camera, :contour_labels, + :connections, ]) const _pgfplotsx_seriestype = [ :path, diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index dd9dd8d9..26735e58 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -203,7 +203,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend}) if hascolorbar(sp) cticks = get_colorbar_ticks(sp)[2] - colorbar_style = PGFPlotsX.Options("title" => sp[:colorbar_title]) + colorbar_style = PGFPlotsX.Options("ylabel" => sp[:colorbar_title]) if sp[:colorbar] === :top push!( colorbar_style, @@ -512,10 +512,29 @@ function pgfx_add_series!(::Val{:heatmap}, axis, series_opt, series, series_func end function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt) - ptable = join( - [string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)], - "\n ", - ) + if opt[:connections] isa Tuple{Array,Array,Array} + # 0-based indexing + ptable = join( + [string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)], + "\n ", + ) + elseif typeof(opt[:connections]) <: AbstractVector{NTuple{3,Int}} + # 1-based indexing + ptable = join( + [ + string(i - 1, " ", j - 1, " ", k - 1, "\\\\") for + (i, j, k) in opt[:connections] + ], + "\n ", + ) + else + throw( + ArgumentError( + "Argument connections has to be either a tuple of three arrays (0-based indexing) + or an AbstractVector{NTuple{3,Int}} (1-based indexing).", + ), + ) + end push!( series_opt, "patch" => nothing, diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index ab09ee80..5269ab14 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -362,6 +362,7 @@ end function plotly_legend_pos(pos::Symbol) xleft = 0.07 + xright = 1.0 ybot = 0.07 ytop = 1.0 xcenter = 0.55 @@ -372,14 +373,14 @@ function plotly_legend_pos(pos::Symbol) xouterright = 1.05 xouterleft = -0.15 plotly_legend_position_mapping = ( - right = (coords = [1.0, ycenter], xanchor = "right", yanchor = "middle"), + right = (coords = [xright, ycenter], xanchor = "right", yanchor = "middle"), left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"), top = (coords = [xcenter, ytop], xanchor = "center", yanchor = "top"), bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"), bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"), - bottomright = (coords = [1.0, ybot], xanchor = "right", yanchor = "bottom"), - topright = (coords = [1.0, 1.0], xanchor = "right", yanchor = "top"), - topleft = (coords = [xleft, 1.0], xanchor = "left", yanchor = "top"), + bottomright = (coords = [xright, ybot], xanchor = "right", yanchor = "bottom"), + topright = (coords = [xright, ytop], xanchor = "right", yanchor = "top"), + topleft = (coords = [xleft, ytop], xanchor = "left", yanchor = "top"), outertop = (coords = [center, youtertop], xanchor = "upper", yanchor = "middle"), outerbottom = (coords = [center, youterbot], xanchor = "lower", yanchor = "middle"), outerleft = (coords = [xouterleft, center], xanchor = "left", yanchor = "top"), @@ -400,7 +401,7 @@ function plotly_legend_pos(pos::Symbol) xanchor = "lower", yanchor = "right", ), - default = (coords = [1.0, 1.0], xanchor = "auto", yanchor = "auto"), + default = (coords = [xright, ytop], xanchor = "auto", yanchor = "auto"), ) legend_position = @@ -678,6 +679,7 @@ function plotly_series(plt::Plot, series::Series) if series[:connections] !== nothing if typeof(series[:connections]) <: Tuple{Array,Array,Array} + # 0-based indexing i, j, k = series[:connections] if !(length(i) == length(j) == length(k)) throw( @@ -689,10 +691,20 @@ function plotly_series(plt::Plot, series::Series) plotattributes_out[:i] = i plotattributes_out[:j] = j plotattributes_out[:k] = k + elseif typeof(series[:connections]) <: AbstractVector{NTuple{3,Int}} + # 1-based indexing + i, j, k = broadcast( + i -> [inds[i] - 1 for inds in series[:connections]], + (1, 2, 3), + ) + plotattributes_out[:i] = i + plotattributes_out[:j] = j + plotattributes_out[:k] = k else throw( ArgumentError( - "Argument connections has to be a tuple of three arrays.", + "Argument connections has to be either a tuple of three arrays (0-based indexing) + or an AbstractVector{NTuple{3,Int}} (1-based indexing).", ), ) end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ce50dec0..fb23ece4 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -29,12 +29,12 @@ if PyPlot.version < v"3.4" @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 >= 3.4.0 - + If you have used Conda.jl to install PyPlot (default installation), upgrade your matplotlib via Conda.jl and rebuild the PyPlot. If you are not sure, here are the default instructions: - + In Julia REPL: ``` import Pkg; @@ -698,6 +698,50 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end end + if st == :mesh3d + polygons = if series[:connections] isa AbstractVector{<:AbstractVector{Int}} + # Combination of any polygon types + broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections]) + elseif series[:connections] isa AbstractVector{NTuple{N,Int}} where {N} + # Only N-gons - connections have to be 1-based (indexing) + broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections]) + elseif series[:connections] isa NTuple{3,<:AbstractVector{Int}} + # Only triangles - connections have to be 0-based (indexing) + ci, cj, ck = series[:connections] + if !(length(ci) == length(cj) == length(ck)) + throw( + ArgumentError( + "Argument connections must consist of equally sized arrays.", + ), + ) + end + broadcast( + j -> broadcast(i -> [x[i], y[i], z[i]], [ci[j] + 1, cj[j] + 1, ck[j] + 1]), + eachindex(ci), + ) + else + throw( + ArgumentError( + "Unsupported `:connections` type $(typeof(series[:connections])) for seriestype=$st", + ), + ) + end + col = mplot3d.art3d.Poly3DCollection( + polygons, + linewidths = py_thickness_scale(plt, series[:linewidth]), + edgecolor = py_color(get_linecolor(series)), + facecolor = py_color(series[:fillcolor]), + alpha = get_fillalpha(series), + zorder = series[:series_plotindex], + ) + handle = ax."add_collection3d"(col) + # Fix for handle: https://stackoverflow.com/questions/54994600/pyplot-legend-poly3dcollection-object-has-no-attribute-edgecolors2d + # It seems there aren't two different alpha values for edge and face + handle._facecolors2d = py_color(series[:fillcolor]) + handle._edgecolors2d = py_color(get_linecolor(series)) + push!(handles, handle) + end + if st == :image xmin, xmax = ignorenan_extrema(series[:x]) ymin, ymax = ignorenan_extrema(series[:y]) @@ -1271,7 +1315,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) end py_set_ticks(sp, ax, ticks, letter) - + if axis[:ticks] == :native # It is easier to reset than to account for this py_set_lims(ax, sp, axis) pyaxis.set_major_locator(pyticker.AutoLocator()) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 8bb64364..a7697c10 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -41,6 +41,7 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend}) end kw = ( + compact = true, title = sp[:title], xlabel = xaxis[:guide], ylabel = yaxis[:guide], @@ -59,9 +60,13 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend}) for ann in sp[:annotations] x, y, val = locate_annotation(sp, ann...) o = UnicodePlots.annotate!( - o, x, y, val.str; + o, + x, + y, + val.str; color = up_color(val.font.color), - halign = val.font.halign, valign = val.font.valign + halign = val.font.halign, + valign = val.font.valign, ) end @@ -78,7 +83,9 @@ up_color(col) = :auto function addUnicodeSeries!( sp::Subplot{UnicodePlotsBackend}, up::UnicodePlots.Plot, - kw, series, addlegend::Bool, + kw, + series, + addlegend::Bool, ) st = series[:seriestype] @@ -100,17 +107,22 @@ function addUnicodeSeries!( cmap = [(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)] return UnicodePlots.heatmap( series[:z].surf; - zlabel = sp[:colorbar_title], colormap = cmap, kw... + zlabel = sp[:colorbar_title], + colormap = cmap, + kw..., ) elseif st == :spy return UnicodePlots.spy(series[:z].surf; kw...) end + series_kw = (;) + # now use the ! functions to add to the plot if st in (:path, :straightline, :shape) func = UnicodePlots.lineplot! elseif st == :scatter || series[:markershape] != :none func = UnicodePlots.scatterplot! + series_kw = (; marker = series[:markershape]) else error("Series type $st not supported by UnicodePlots") end @@ -120,13 +132,25 @@ function addUnicodeSeries!( for (n, segment) in enumerate(series_segments(series, st; check = true)) i, rng = segment.attr_index, segment.range lc = get_linecolor(series, i) - up = func(up, x[rng], y[rng]; color = up_color(lc), name = n == 1 ? label : "") + up = func( + up, + x[rng], + y[rng]; + color = up_color(lc), + name = n == 1 ? label : "", + series_kw..., + ) end for (xi, yi, str, fnt) in EachAnn(series[:series_annotations], x, y) up = UnicodePlots.annotate!( - up, xi, yi, str; - color = up_color(fnt.color), halign = fnt.halign, valign = fnt.valign + up, + xi, + yi, + str; + color = up_color(fnt.color), + halign = fnt.halign, + valign = fnt.valign, ) end @@ -158,7 +182,7 @@ function png(plt::Plot{UnicodePlotsBackend}, fn::AbstractString) error( "Can only savepng on MacOS or Linux with UnicodePlots " * - "(though even then I wouldn't do it)" + "(though even then I wouldn't do it)", ) end @@ -200,7 +224,7 @@ function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) end l_max[r] = lmax end - empty = String[' '^w for w ∈ w_max] + empty = String[' '^w for w in w_max] for r in 1:nr for n in 1:l_max[r] for c in 1:nc diff --git a/src/colorbars.jl b/src/colorbars.jl index db59c7ef..2717da5b 100644 --- a/src/colorbars.jl +++ b/src/colorbars.jl @@ -5,33 +5,32 @@ process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema # don't specialize on ::Function otherwise python functions won't work process_clims(f) = f -function get_clims(sp::Subplot, op = process_clims(sp[:clims])) +get_clims(sp::Subplot)::Tuple{Float64,Float64} = sp[:crange] +get_clims(series::Series)::Tuple{Float64,Float64} = series[:crange] + +get_clims(sp::Subplot, series::Series)::Tuple{Float64,Float64} = + series[:colorbar_entry] ? sp[:crange] : series[:crange] + +function update_clims(sp::Subplot, op = process_clims(sp[:clims]))::Tuple{Float64,Float64} zmin, zmax = Inf, -Inf for series in series_list(sp) if series[:colorbar_entry] - zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...) + zmin, zmax = _update_clims(zmin, zmax, update_clims(series, op)...) + else + update_clims(series, op) end end - return zmin <= zmax ? (zmin, zmax) : (NaN, NaN) -end - -function get_clims(sp::Subplot, series::Series, op = process_clims(sp[:clims])) - zmin, zmax = if series[:colorbar_entry] - get_clims(sp, op) - else - get_clims(series, op) - end - return zmin <= zmax ? (zmin, zmax) : (NaN, NaN) + return sp[:crange] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN) end """ - get_clims(::Series, op=Plots.ignorenan_extrema) + update_clims(::Series, op=Plots.ignorenan_extrema) Finds the limits for the colorbar by taking the "z-values" for the series and passing them into `op`, which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite -values of the input. +values of the input. The value is stored as a series property, which is retrieved by `get_clims`. """ -function get_clims(series::Series, op = ignorenan_extrema) +function update_clims(series::Series, op = ignorenan_extrema)::Tuple{Float64,Float64} zmin, zmax = Inf, -Inf z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin) for vals in ( @@ -46,7 +45,7 @@ function get_clims(series::Series, op = ignorenan_extrema) zmin, zmax = _update_clims(zmin, zmax, op(vals)...) end end - return zmin <= zmax ? (zmin, zmax) : (NaN, NaN) + return series[:crange] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN) end _update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax) @@ -94,4 +93,5 @@ end function _update_subplot_colorbars(sp::Subplot) # Dynamic callback from the pipeline if needed + update_clims(sp) end diff --git a/src/examples.jl b/src/examples.jl index d1e1a474..049e5172 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -962,8 +962,10 @@ const _examples = PlotExample[ """ Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically. You can also specify the connections using the connections keyword. - The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle, - such that elements at the same position of these vectors form a triangle. + The connections can be specified in two ways: Either as a tuple of vectors where each vector + contains the 0-based indices of one point of a triangle, such that elements at the same + position of these vectors form a triangle. Or as a vector of NTuple{3,Ints} where each element + contains the 1-based indices of the three points of a triangle. """, [ :( @@ -979,13 +981,14 @@ const _examples = PlotExample[ i = [0, 0, 0, 1] j = [1, 2, 3, 2] k = [2, 3, 1, 3] + # Or: cns = [(1, 2, 3), (1, 3, 4), (1, 4, 2), (2, 3, 4)] (1-based indexing) # the four triangles gives above give a tetrahedron mesh3d( x, y, z; - connections = (i, j, k), + connections = (i, j, k), # connections = cns title = "triangles", xlabel = "x", ylabel = "y", @@ -1235,7 +1238,7 @@ const _examples = PlotExample[ _animation_examples = [2, 31] _backend_skips = Dict( :gr => [25, 30], - :pyplot => [2, 25, 30, 31, 47, 49, 55], + :pyplot => [2, 25, 30, 31, 49, 55], :plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51, 55], :plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55], :pgfplotsx => [ @@ -1252,7 +1255,6 @@ _backend_skips = Dict( :unicodeplots => [ 5, # limits issue 6, # embedded images unsupported - 13, # markers unsupported 16, # nested layout unsupported 21, # custom markers unsupported 22, # contours unsupported @@ -1266,7 +1268,6 @@ _backend_skips = Dict( 43, # heatmap with DateTime 45, # error bars 47, # mesh3D unsupported - 48, # markershapes unsupported 49, # polar heatmap 50, # 3D surface unsupported 51, # embedded images unsupported diff --git a/src/pipeline.jl b/src/pipeline.jl index 476b4256..9de412b7 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -416,4 +416,5 @@ function _add_the_series(plt, sp, plotattributes) push!(plt.series_list, series) push!(sp.series_list, series) _series_added(plt, series) + _update_subplot_colorbars(sp) end diff --git a/src/precompile_includer.jl b/src/precompile_includer.jl index c5df391f..2a19fe91 100644 --- a/src/precompile_includer.jl +++ b/src/precompile_includer.jl @@ -7,10 +7,9 @@ ismultiversion = false @static if !should_precompile # nothing elseif !ismultios && !ismultiversion - @static if isfile(joinpath( - @__DIR__, - "../deps/SnoopCompile/precompile/precompile_Plots.jl", - )) + @static if isfile( + joinpath(@__DIR__, "../deps/SnoopCompile/precompile/precompile_Plots.jl"), + ) include("../deps/SnoopCompile/precompile/precompile_Plots.jl") _precompile_() end diff --git a/src/recipes.jl b/src/recipes.jl index d97d1f0d..ef045446 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -1042,7 +1042,13 @@ export lens! series_plotindex := backup[:series_plotindex] seriestype := :path primary := false - linecolor := :lightgray + linecolor := get(backup, :linecolor, :lightgray) + if haskey(backup, :linestyle) + linestyle := backup[:linestyle] + end + if haskey(backup, :linewidth) + linewidth := backup[:linewidth] + end bbx_mag = (x1 + x2) / 2 bby_mag = (y1 + y2) / 2 xi_lens, yi_lens = diff --git a/src/utils.jl b/src/utils.jl index c90f90e6..5f6d3c59 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -205,13 +205,14 @@ maketuple(x::Tuple{T,S}) where {T,S} = x for i in 2:4 @eval begin RecipesPipeline.unzip( - v::Union{AVec{<:NTuple{$i,T} where T},AVec{<:GeometryBasics.Point{$i}}}, + v::Union{AVec{<:NTuple{$i,T} where {T}},AVec{<:GeometryBasics.Point{$i}}}, ) = $(Expr(:tuple, (:([t[$j] for t in v]) for j in 1:i)...)) end end -RecipesPipeline.unzip(::Union{AVec{<:GeometryBasics.Point{N}},AVec{<:NTuple{N,T} where T}}) where {N} = - error("$N-dimensional unzip not implemented.") +RecipesPipeline.unzip( + ::Union{AVec{<:GeometryBasics.Point{N}},AVec{<:NTuple{N,T} where {T}}}, +) where {N} = error("$N-dimensional unzip not implemented.") RecipesPipeline.unzip(::Union{AVec{<:GeometryBasics.Point},AVec{<:Tuple}}) = error("Can't unzip points of different dimensions.") @@ -1180,16 +1181,10 @@ end _document_argument(S::AbstractString) = _fmt_paragraph("`$S`: " * _arg_desc[Symbol(S)], leadingspaces = 6 + length(S)) -function mesh3d_triangles(x, y, z, cns) - if typeof(cns) <: Tuple{Array,Array,Array} - ci, cj, ck = cns - if !(length(ci) == length(cj) == length(ck)) - throw( - ArgumentError("Argument connections must consist of equally sized arrays."), - ) - end - else - throw(ArgumentError("Argument connections has to be a tuple of three arrays.")) +function mesh3d_triangles(x, y, z, cns::Tuple{Array,Array,Array}) + ci, cj, ck = cns + if !(length(ci) == length(cj) == length(ck)) + throw(ArgumentError("Argument connections must consist of equally sized arrays.")) end X = zeros(eltype(x), 4length(ci)) Y = zeros(eltype(y), 4length(cj)) @@ -1214,6 +1209,30 @@ function mesh3d_triangles(x, y, z, cns) end return X, Y, Z end +function mesh3d_triangles(x, y, z, cns::AbstractVector{NTuple{3,Int}}) + X = zeros(eltype(x), 4length(cns)) + Y = zeros(eltype(y), 4length(cns)) + Z = zeros(eltype(z), 4length(cns)) + @inbounds for I in 1:length(cns) + i = cns[I][1] # connections are 1-based + j = cns[I][2] + k = cns[I][3] + m = 4(I - 1) + 1 + n = m + 1 + o = m + 2 + p = m + 3 + X[m] = X[p] = x[i] + Y[m] = Y[p] = y[i] + Z[m] = Z[p] = z[i] + X[n] = x[j] + Y[n] = y[j] + Z[n] = z[j] + X[o] = x[k] + Y[o] = y[k] + Z[o] = z[k] + end + return X, Y, Z +end # cache joined symbols so they can be looked up instead of constructed each time const _attrsymbolcache = Dict{Symbol,Dict{Symbol,Symbol}}() diff --git a/test/runtests.jl b/test/runtests.jl index 7f8057e8..a69099bb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -155,7 +155,8 @@ end end @testset "EmptyAnim" begin - anim = @animate for i in [] end + anim = @animate for i in [] + end @test_throws ArgumentError gif(anim) end @@ -200,7 +201,6 @@ end Plots.process_clims(:auto) end - @testset "Backends" begin @testset "UnicodePlots" begin @test unicodeplots() == Plots.UnicodePlotsBackend() diff --git a/test/test_axes.jl b/test/test_axes.jl index f041746f..cd184708 100644 --- a/test/test_axes.jl +++ b/test/test_axes.jl @@ -73,18 +73,18 @@ end @test p[1][:xaxis][:ticks] == [1.25, 1.5, 1.75] p = plot(1:2, xlabelfontsize = 4) @test p[1][:xaxis][:guidefontsize] == 4 - p = plot(1:2, xgα = .07) - @test p[1][:xaxis][:gridalpha] ≈ .07 + p = plot(1:2, xgα = 0.07) + @test p[1][:xaxis][:gridalpha] ≈ 0.07 p = plot(1:2, xgridls = :dashdot) @test p[1][:xaxis][:gridstyle] === :dashdot p = plot(1:2, xgridcolor = :red) - @test p[1][:xaxis][:foreground_color_grid] === RGBA{Float64}(1.,0.,0.,1.) + @test p[1][:xaxis][:foreground_color_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0) p = plot(1:2, xminorgridcolor = :red) - @test p[1][:xaxis][:foreground_color_minor_grid] === RGBA{Float64}(1.,0.,0.,1.) - p = plot(1:2, xgrid_lw = .01) - @test p[1][:xaxis][:gridlinewidth] ≈ .01 - p = plot(1:2, xminorgrid_lw = .01) - @test p[1][:xaxis][:minorgridlinewidth] ≈ .01 + @test p[1][:xaxis][:foreground_color_minor_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0) + p = plot(1:2, xgrid_lw = 0.01) + @test p[1][:xaxis][:gridlinewidth] ≈ 0.01 + p = plot(1:2, xminorgrid_lw = 0.01) + @test p[1][:xaxis][:minorgridlinewidth] ≈ 0.01 p = plot(1:2, xtickor = :out) @test p[1][:xaxis][:tick_direction] === :out end @@ -97,24 +97,23 @@ end p = plot(1:2, label = "test") @test compare(p, :guide, "", ===) p = plot(1:2, lim = (0, 3)) - @test xlims(p) === ylims(p) === zlims(p) === (0,3) + @test xlims(p) === ylims(p) === zlims(p) === (0, 3) p = plot(1:2, tick = [1.25, 1.5, 1.75]) - @test compare(p,:ticks,[1.25, 1.5, 1.75], ==) + @test compare(p, :ticks, [1.25, 1.5, 1.75], ==) p = plot(1:2, labelfontsize = 4) - @test compare(p,:guidefontsize,4, ==) - p = plot(1:2, gα = .07) - @test compare(p,:gridalpha,.07, ≈) + @test compare(p, :guidefontsize, 4, ==) + p = plot(1:2, gα = 0.07) + @test compare(p, :gridalpha, 0.07, ≈) p = plot(1:2, gridls = :dashdot) - @test compare(p,:gridstyle,:dashdot, ===) + @test compare(p, :gridstyle, :dashdot, ===) p = plot(1:2, gridcolor = :red) - @test compare(p,:foreground_color_grid,RGBA{Float64}(1.,0.,0.,1.), ===) + @test compare(p, :foreground_color_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===) p = plot(1:2, minorgridcolor = :red) - @test compare(p,:foreground_color_minor_grid,RGBA{Float64}(1.,0.,0.,1.), ===) - p = plot(1:2, grid_lw = .01) - @test compare(p,:gridlinewidth,.01, ≈) - p = plot(1:2, minorgrid_lw = .01) - @test compare(p,:minorgridlinewidth,.01, ≈) + @test compare(p, :foreground_color_minor_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===) + p = plot(1:2, grid_lw = 0.01) + @test compare(p, :gridlinewidth, 0.01, ≈) + p = plot(1:2, minorgrid_lw = 0.01) + @test compare(p, :minorgridlinewidth, 0.01, ≈) p = plot(1:2, tickor = :out) - @test compare(p,:tick_direction,:out, ===) - + @test compare(p, :tick_direction, :out, ===) end