Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f063c71b5 | |||
| 1e9691a7c0 | |||
| e5269bcf95 | |||
| fdd76a6ca1 | |||
| d19525c269 | |||
| 593331dec2 | |||
| b780d90097 | |||
| 2f9ce790e4 | |||
| d8f4519b0c | |||
| 702e41f55d | |||
| 682ac29fcd | |||
| c6ce23d0af | |||
| 9ae7d2dd9d | |||
| 6ec05628d5 | |||
| f26ebdc2f1 | |||
| c97255fc08 | |||
| 9d1ede016b | |||
| 7eb8f2452c | |||
| 0a6e691222 | |||
| 238aca6a78 |
@@ -7,7 +7,7 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please search existing issues to avoid duplicates.
|
||||
<!-- Please search existing issues to avoid duplicates. -->
|
||||
|
||||
## Details
|
||||
|
||||
@@ -28,5 +28,5 @@ inspectdr | | |
|
||||
### Versions
|
||||
|
||||
Plots.jl version:
|
||||
Backend version:
|
||||
Backend version (`]st -m`):
|
||||
Output of `versioninfo()`:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
name = "Plots"
|
||||
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
author = ["Tom Breloff (@tbreloff)"]
|
||||
version = "1.2.4"
|
||||
version = "1.3.2"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
|
||||
@@ -97,6 +97,7 @@ const _arg_desc = KW(
|
||||
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
|
||||
:legendfontrotation => "Real. Font rotation of legend entries",
|
||||
:legendfontcolor => "Color Type. Font color of legend entries",
|
||||
:legendtitle => "String. Legend title.",
|
||||
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.",
|
||||
:legendtitlefontsize => "Integer. Font pointsize the legend title.",
|
||||
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
|
||||
|
||||
+6
-2
@@ -190,11 +190,15 @@ function backend(sym::Symbol)
|
||||
end
|
||||
end
|
||||
|
||||
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize]
|
||||
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize, :pgfplots]
|
||||
|
||||
function warn_on_deprecated_backend(bsym::Symbol)
|
||||
if bsym in _deprecated_backends
|
||||
@warn("Backend $bsym has been deprecated.")
|
||||
if bsym == :pgfplots
|
||||
@warn("Backend $bsym has been deprecated. Use pgfplotsx instead.")
|
||||
else
|
||||
@warn("Backend $bsym has been deprecated.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+92
-56
@@ -136,17 +136,12 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
bgc_inside = plot_color(sp[:background_color_inside])
|
||||
bgc_inside_a = alpha(bgc_inside)
|
||||
axis_opt = PGFPlotsX.Options(
|
||||
"point meta max" => get_clims(sp)[2],
|
||||
"point meta min" => get_clims(sp)[1],
|
||||
"legend cell align" => "left",
|
||||
"title" => sp[:title],
|
||||
"title style" => PGFPlotsX.Options(
|
||||
"at" => if title_loc == :left
|
||||
"{(0,1)}"
|
||||
elseif title_loc == :right
|
||||
"{(1,1)}"
|
||||
elseif title_loc isa Tuple
|
||||
"{$(string(title_loc))}"
|
||||
else
|
||||
"{(0.5,1)}"
|
||||
end,
|
||||
pgfx_get_title_pos(title_loc)...,
|
||||
"font" => pgfx_font(
|
||||
sp[:titlefontsize],
|
||||
pgfx_thickness_scaling(sp),
|
||||
@@ -184,12 +179,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
sp_height > 0 * mm ? push!(axis_opt, "height" => string(axis_height)) :
|
||||
nothing
|
||||
# legend position
|
||||
if sp[:legend] isa Tuple
|
||||
x, y = sp[:legend]
|
||||
push!(axis_opt["legend style"], "at={($x, $y)}")
|
||||
else
|
||||
push!(axis_opt["legend style"], pgfx_get_legend_pos(sp[:legend])...)
|
||||
end
|
||||
push!(axis_opt["legend style"], pgfx_get_legend_pos(sp[:legend])...)
|
||||
for letter in (:x, :y, :z)
|
||||
if letter != :z || RecipesPipeline.is3d(sp)
|
||||
pgfx_axis!(axis_opt, sp, letter)
|
||||
@@ -206,41 +196,48 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
# As it is likely that all series within the same axis use the same
|
||||
# colormap this should not cause any problem.
|
||||
for series in series_list(sp)
|
||||
if hascolorbar(series)
|
||||
cg = get_colorgradient(series)
|
||||
cm = pgfx_colormap(get_colorgradient(series))
|
||||
PGFPlotsX.push_preamble!(
|
||||
pgfx_plot.the_plot,
|
||||
"""\\pgfplotsset{
|
||||
colormap={plots$(sp.attr[:subplot_index])}{$cm},
|
||||
}""",
|
||||
)
|
||||
if hascolorbar(series)
|
||||
cg = get_colorgradient(series)
|
||||
cm = pgfx_colormap(get_colorgradient(series))
|
||||
PGFPlotsX.push_preamble!(
|
||||
pgfx_plot.the_plot,
|
||||
"""\\pgfplotsset{
|
||||
colormap={plots$(sp.attr[:subplot_index])}{$cm},
|
||||
}""",
|
||||
)
|
||||
push!(axis_opt, "colormap name" => "plots$(sp.attr[:subplot_index])")
|
||||
if cg isa PlotUtils.CategoricalColorGradient
|
||||
push!(
|
||||
axis_opt,
|
||||
"colorbar" => nothing,
|
||||
"colormap name" => "plots$(sp.attr[:subplot_index])",
|
||||
"colormap access" => "piecewise const",
|
||||
"colorbar sampled" => nothing,
|
||||
)
|
||||
if cg isa PlotUtils.CategoricalColorGradient
|
||||
push!(
|
||||
axis_opt,
|
||||
"colormap access" => "piecewise const",
|
||||
"colorbar sampled" => nothing,
|
||||
)
|
||||
end
|
||||
# goto is needed to break out of col and series for
|
||||
@goto colorbar_end
|
||||
end
|
||||
# goto is needed to break out of col and series for
|
||||
@goto colorbar_end
|
||||
end
|
||||
end
|
||||
@label colorbar_end
|
||||
|
||||
push!(
|
||||
axis_opt,
|
||||
"colorbar style" => PGFPlotsX.Options(
|
||||
if hascolorbar(sp)
|
||||
colorbar_style = PGFPlotsX.Options(
|
||||
"title" => sp[:colorbar_title],
|
||||
),
|
||||
"point meta max" => get_clims(sp)[2],
|
||||
"point meta min" => get_clims(sp)[1],
|
||||
)
|
||||
"xticklabel style" => pgfx_get_ticklabel_style(sp, sp[:xaxis]),
|
||||
"yticklabel style" => pgfx_get_ticklabel_style(sp, sp[:yaxis]),
|
||||
)
|
||||
if sp[:colorbar] === :top
|
||||
push!(colorbar_style,
|
||||
"at" => string((0.5, 1.05)),
|
||||
"anchor" => "south",
|
||||
"xticklabel pos" => "upper",
|
||||
)
|
||||
end
|
||||
push!(
|
||||
axis_opt,
|
||||
string("colorbar", pgfx_get_colorbar_pos(sp[:colorbar])) => nothing,
|
||||
"colorbar style" => colorbar_style,
|
||||
)
|
||||
end
|
||||
if RecipesPipeline.is3d(sp)
|
||||
azim, elev = sp[:camera]
|
||||
push!(axis_opt, "view" => (azim, elev))
|
||||
@@ -646,6 +643,26 @@ pgfx_get_marker(k) = get(
|
||||
"*",
|
||||
)
|
||||
|
||||
pgfx_get_xguide_pos(k) = get(
|
||||
(
|
||||
top = "at={(0.5,1)},above,",
|
||||
right = "at={(ticklabel* cs:1.02)}, anchor=west,",
|
||||
left = "at={(ticklabel* cs:-0.02)}, anchor=east,",
|
||||
),
|
||||
k,
|
||||
"at={(ticklabel cs:0.5)}, anchor=near ticklabel"
|
||||
)
|
||||
|
||||
pgfx_get_yguide_pos(k) = get(
|
||||
(
|
||||
top = "at={(ticklabel* cs:1.02)}, anchor=south",
|
||||
right = "at={(1,0.5)},below,",
|
||||
bottom = "at={(ticklabel* cs:-0.02)}, anchor=north,",
|
||||
),
|
||||
k,
|
||||
"at={(ticklabel cs:0.5)}, anchor=near ticklabel"
|
||||
)
|
||||
|
||||
pgfx_get_legend_pos(k) = get(
|
||||
(
|
||||
top = ("at" => string((0.5, 0.98)), "anchor" => "north"),
|
||||
@@ -668,6 +685,33 @@ pgfx_get_legend_pos(k) = get(
|
||||
Symbol(k),
|
||||
("at" => string((1.02, 1)), "anchor" => "north west"),
|
||||
)
|
||||
pgfx_get_legend_pos(t::Tuple) = ("at" => "{$(string(t))}", "anchor" => "north west")
|
||||
pgfx_get_legend_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
|
||||
pgfx_get_colorbar_pos(s) =
|
||||
get((left = " left", bottom = " horizontal", top = " horizontal"), s, "")
|
||||
pgfx_get_colorbar_pos(b::Bool) = ""
|
||||
|
||||
pgfx_get_title_pos(s) =
|
||||
get((
|
||||
left = ("at" => "{(0,1)}", "anchor" => "south west"),
|
||||
right = ("at" => "{(1,1)}", "anchor" => "south east"),
|
||||
), s,
|
||||
("at" => "{(0.5,1)}", "anchor" => "south"))
|
||||
pgfx_get_title_pos(t::Tuple) = ("at" => "{$(string(t))}", "anchor" => "south")
|
||||
pgfx_get_title_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
|
||||
function pgfx_get_ticklabel_style(sp, axis)
|
||||
cstr = plot_color(axis[:tickfontcolor])
|
||||
return PGFPlotsX.Options(
|
||||
"font" => pgfx_font(
|
||||
axis[:tickfontsize], pgfx_thickness_scaling(sp)
|
||||
),
|
||||
"color" => cstr,
|
||||
"draw opacity" => alpha(cstr),
|
||||
"rotate" => axis[:tickfontrotation],
|
||||
)
|
||||
end
|
||||
|
||||
## --------------------------------------------------------------------------------------
|
||||
# Generates a colormap for pgfplots based on a ColorGradient
|
||||
@@ -1009,10 +1053,10 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
|
||||
# axis label position
|
||||
labelpos = ""
|
||||
if letter == :x && axis[:guide_position] == :top
|
||||
labelpos = "at={(0.5,1)},above,"
|
||||
elseif letter == :y && axis[:guide_position] == :right
|
||||
labelpos = "at={(1,0.5)},below,"
|
||||
if letter == :x
|
||||
labelpos = pgfx_get_xguide_pos(axis[:guide_position])
|
||||
elseif letter == :y
|
||||
labelpos = pgfx_get_yguide_pos(axis[:guide_position])
|
||||
end
|
||||
|
||||
# Add label font
|
||||
@@ -1105,17 +1149,8 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
string(letter, "tick align") =>
|
||||
(axis[:tick_direction] == :out ? "outside" : "inside"),
|
||||
)
|
||||
cstr = plot_color(axis[:tickfontcolor])
|
||||
α = alpha(cstr)
|
||||
push!(
|
||||
opt,
|
||||
string(letter, "ticklabel style") => PGFPlotsX.Options(
|
||||
"font" =>
|
||||
pgfx_font(axis[:tickfontsize], pgfx_thickness_scaling(sp)),
|
||||
"color" => cstr,
|
||||
"draw opacity" => α,
|
||||
"rotate" => axis[:tickfontrotation],
|
||||
),
|
||||
opt, string(letter, "ticklabel style") => pgfx_get_ticklabel_style(sp, axis)
|
||||
)
|
||||
push!(
|
||||
opt,
|
||||
@@ -1203,6 +1238,7 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
# display calls this and then _display, its called 3 times for plot(1:5)
|
||||
# Set the (left, top, right, bottom) minimum padding around the plot area
|
||||
|
||||
@@ -336,7 +336,7 @@ function plotly_layout(plt::Plot)
|
||||
plotattributes_out[:hovermode] = "none"
|
||||
end
|
||||
|
||||
plotattributes_out
|
||||
plotattributes_out = recursive_merge(plotattributes_out, plt.attr[:extra_plot_kwargs])
|
||||
end
|
||||
|
||||
function plotly_layout_json(plt::Plot)
|
||||
@@ -810,9 +810,14 @@ html_body(plt::Plot{PlotlyBackend}) = plotly_html_body(plt)
|
||||
const ijulia_initialized = Ref(false)
|
||||
|
||||
function plotly_html_head(plt::Plot)
|
||||
local_file = ("file://" * plotly_local_file_path)
|
||||
local_file = ("file:///" * plotly_local_file_path)
|
||||
plotly =
|
||||
use_local_dependencies[] ? local_file : "https://cdn.plot.ly/plotly-latest.min.js"
|
||||
|
||||
include_mathjax = get(plt[:extra_plot_kwargs], :include_mathjax, "")
|
||||
mathjax_file = include_mathjax != "cdn" ? ("file://" * include_mathjax) : "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"
|
||||
mathjax_head = include_mathjax == "" ? "" : "<script src=\"$mathjax_file\"></script>\n\t\t"
|
||||
|
||||
if isijulia() && !ijulia_initialized[]
|
||||
# using requirejs seems to be key to load a js depency in IJulia!
|
||||
# https://requirejs.org/docs/start.html
|
||||
@@ -826,7 +831,7 @@ function plotly_html_head(plt::Plot)
|
||||
""")
|
||||
ijulia_initialized[] = true
|
||||
end
|
||||
return "<script src=$(repr(plotly))></script>"
|
||||
return "$mathjax_head<script src=$(repr(plotly))></script>"
|
||||
end
|
||||
|
||||
function plotly_html_body(plt, style = nothing)
|
||||
|
||||
@@ -589,6 +589,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
||||
push!(handles, handle)
|
||||
else
|
||||
# do a normal scatter plot
|
||||
|
||||
# Add depthshade option for 3d plots
|
||||
if RecipesPipeline.is3d(sp)
|
||||
extrakw[:depthshade] = get(series[:extra_kwargs], :depthshade, false)
|
||||
end
|
||||
|
||||
handle = ax."scatter"(xyargs...;
|
||||
label = series[:label],
|
||||
zorder = series[:series_plotindex] + 0.5,
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ function __init__()
|
||||
end
|
||||
|
||||
@require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" begin
|
||||
fn = joinpath(@__DIR__, "backends", "pgfplots.jl")
|
||||
fn = joinpath(@__DIR__, "backends", "deprecated", "pgfplots.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@@ -302,6 +302,11 @@ Base.convert(::Type{Vector{T}}, rng::AbstractRange{S}) where {T<:Real,S<:Real} =
|
||||
|
||||
Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
|
||||
|
||||
# recursively merge kw-dicts, e.g. for merging extra_kwargs / extra_plot_kwargs in plotly)
|
||||
recursive_merge(x::AbstractDict...) = merge(recursive_merge, x...)
|
||||
# if values are not AbstractDicts, take the last definition (as does merge)
|
||||
recursive_merge(x...) = x[end]
|
||||
|
||||
nanpush!(a::AbstractVector, b) = (push!(a, NaN); push!(a, b))
|
||||
nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user