Merge branch 'master' into add-stride
This commit is contained in:
commit
c7eb22021f
13
NEWS.md
13
NEWS.md
@ -11,14 +11,23 @@
|
|||||||
---
|
---
|
||||||
## (current master)
|
## (current master)
|
||||||
|
|
||||||
## 0.12.2
|
## 0.12.3
|
||||||
|
|
||||||
|
- new grid line style defaults
|
||||||
|
- `grid` is now an axis attribute and a magic argument: it is now possible to modify the grid line style, alpha and line width
|
||||||
|
- Enforce plot order in user recipes
|
||||||
|
- import `plot!` from RecipesBase
|
||||||
|
- GR no longer automatically handles _ and ^ in texts
|
||||||
|
- fix GR colorbar for scatter plots
|
||||||
|
|
||||||
|
#### 0.12.2
|
||||||
|
|
||||||
- fix an issue with Juno/PlotlyJS compatibility on new installations
|
- fix an issue with Juno/PlotlyJS compatibility on new installations
|
||||||
- fix markers not showing up in seriesrecipes using :scatter
|
- fix markers not showing up in seriesrecipes using :scatter
|
||||||
- don't use pywrap in the pyplot backend
|
- don't use pywrap in the pyplot backend
|
||||||
- improve the bottom margin for the gr backend
|
- improve the bottom margin for the gr backend
|
||||||
|
|
||||||
## 0.12.1
|
#### 0.12.1
|
||||||
|
|
||||||
- fix deprecation warnings
|
- fix deprecation warnings
|
||||||
- switch from FixedSizeArrays to StaticArrays.FixedSizeArrays
|
- switch from FixedSizeArrays to StaticArrays.FixedSizeArrays
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# Plots
|
# Plots
|
||||||
|
|
||||||
[](https://travis-ci.org/JuliaPlots/Plots.jl)
|
[](https://travis-ci.org/JuliaPlots/Plots.jl)
|
||||||
|
[](https://ci.appveyor.com/project/tbreloff/plots-jl)
|
||||||
[](https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
<!-- [](http://pkg.julialang.org/?pkg=Plots&ver=0.3) -->
|
<!-- [](http://pkg.julialang.org/?pkg=Plots&ver=0.3) -->
|
||||||
<!-- [](http://pkg.julialang.org/?pkg=Plots&ver=0.4) -->
|
<!-- [](http://pkg.julialang.org/?pkg=Plots&ver=0.4) -->
|
||||||
|
|||||||
2
REQUIRE
2
REQUIRE
@ -1,4 +1,4 @@
|
|||||||
julia 0.6-pre
|
julia 0.6
|
||||||
|
|
||||||
RecipesBase 0.2.0
|
RecipesBase 0.2.0
|
||||||
PlotUtils 0.4.1
|
PlotUtils 0.4.1
|
||||||
|
|||||||
10
appveyor.yml
10
appveyor.yml
@ -1,7 +1,13 @@
|
|||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.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.5/julia-0.5-latest-win64.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://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/x86/julia-latest-win32.exe"
|
||||||
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
|
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
|
||||||
|
|
||||||
|
|||||||
40
src/Plots.jl
40
src/Plots.jl
@ -8,7 +8,7 @@ import StaticArrays
|
|||||||
using StaticArrays.FixedSizeArrays
|
using StaticArrays.FixedSizeArrays
|
||||||
|
|
||||||
@reexport using RecipesBase
|
@reexport using RecipesBase
|
||||||
import RecipesBase: plot, animate
|
import RecipesBase: plot, plot!, animate
|
||||||
using Base.Meta
|
using Base.Meta
|
||||||
@reexport using PlotUtils
|
@reexport using PlotUtils
|
||||||
@reexport using PlotThemes
|
@reexport using PlotThemes
|
||||||
@ -52,6 +52,8 @@ export
|
|||||||
yflip!,
|
yflip!,
|
||||||
xaxis!,
|
xaxis!,
|
||||||
yaxis!,
|
yaxis!,
|
||||||
|
xgrid!,
|
||||||
|
ygrid!,
|
||||||
|
|
||||||
xlims,
|
xlims,
|
||||||
ylims,
|
ylims,
|
||||||
@ -186,33 +188,65 @@ include("output.jl")
|
|||||||
@shorthands quiver
|
@shorthands quiver
|
||||||
@shorthands curves
|
@shorthands curves
|
||||||
|
|
||||||
|
"Plot a pie diagram"
|
||||||
pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
||||||
pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
||||||
|
|
||||||
|
"Plot with seriestype :path3d"
|
||||||
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
|
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
|
||||||
plot3d!(args...; kw...) = plot!(args...; kw..., seriestype = :path3d)
|
plot3d!(args...; kw...) = plot!(args...; kw..., seriestype = :path3d)
|
||||||
|
|
||||||
|
"Add title to an existing plot"
|
||||||
title!(s::AbstractString; kw...) = plot!(; title = s, kw...)
|
title!(s::AbstractString; kw...) = plot!(; title = s, kw...)
|
||||||
|
|
||||||
|
"Add xlabel to an existing plot"
|
||||||
xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...)
|
xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...)
|
||||||
|
|
||||||
|
"Add ylabel to an existing plot"
|
||||||
ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...)
|
ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...)
|
||||||
|
|
||||||
|
"Set xlims for an existing plot"
|
||||||
xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; xlims = lims, kw...)
|
xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; xlims = lims, kw...)
|
||||||
|
|
||||||
|
"Set ylims for an existing plot"
|
||||||
ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; ylims = lims, kw...)
|
ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; ylims = lims, kw...)
|
||||||
|
|
||||||
|
"Set zlims for an existing plot"
|
||||||
zlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; zlims = lims, kw...)
|
zlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; zlims = lims, kw...)
|
||||||
|
|
||||||
xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...)
|
xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...)
|
||||||
ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...)
|
ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...)
|
||||||
zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...)
|
zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...)
|
||||||
|
|
||||||
|
|
||||||
|
"Set xticks for an existing plot"
|
||||||
xticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; xticks = v, kw...)
|
xticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; xticks = v, kw...)
|
||||||
|
|
||||||
|
"Set yticks for an existing plot"
|
||||||
yticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; yticks = v, kw...)
|
yticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; yticks = v, kw...)
|
||||||
|
|
||||||
xticks!{T<:Real,S<:AbstractString}(
|
xticks!{T<:Real,S<:AbstractString}(
|
||||||
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; xticks = (ticks,labels), kw...)
|
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; xticks = (ticks,labels), kw...)
|
||||||
yticks!{T<:Real,S<:AbstractString}(
|
yticks!{T<:Real,S<:AbstractString}(
|
||||||
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; yticks = (ticks,labels), kw...)
|
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; yticks = (ticks,labels), kw...)
|
||||||
|
|
||||||
|
"Add annotations to an existing plot"
|
||||||
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
|
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
|
||||||
annotate!{T<:Tuple}(anns::AVec{T}; kw...) = plot!(; annotation = anns, kw...)
|
annotate!{T<:Tuple}(anns::AVec{T}; kw...) = plot!(; annotation = anns, kw...)
|
||||||
|
|
||||||
|
"Flip the current plots' x axis"
|
||||||
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
|
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
|
||||||
|
|
||||||
|
"Flip the current plots' y axis"
|
||||||
yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
|
yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
|
||||||
|
|
||||||
|
"Specify x axis attributes for an existing plot"
|
||||||
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
|
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
|
||||||
|
|
||||||
|
"Specify x axis attributes for an existing plot"
|
||||||
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
|
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
|
||||||
|
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||||
|
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
|
||||||
|
|
||||||
let PlotOrSubplot = Union{Plot, Subplot}
|
let PlotOrSubplot = Union{Plot, Subplot}
|
||||||
title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...)
|
title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...)
|
||||||
@ -230,6 +264,8 @@ let PlotOrSubplot = Union{Plot, Subplot}
|
|||||||
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; xticks = (ticks,labels), kw...)
|
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; xticks = (ticks,labels), kw...)
|
||||||
yticks!{T<:Real,S<:AbstractString}(plt::PlotOrSubplot,
|
yticks!{T<:Real,S<:AbstractString}(plt::PlotOrSubplot,
|
||||||
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; yticks = (ticks,labels), kw...)
|
ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; yticks = (ticks,labels), kw...)
|
||||||
|
xgrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; xgrid = args, kw...)
|
||||||
|
ygrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; ygrid = args, kw...)
|
||||||
annotate!(plt::PlotOrSubplot, anns...; kw...) = plot!(plt; annotation = anns, kw...)
|
annotate!(plt::PlotOrSubplot, anns...; kw...) = plot!(plt; annotation = anns, kw...)
|
||||||
annotate!{T<:Tuple}(plt::PlotOrSubplot, anns::AVec{T}; kw...) = plot!(plt; annotation = anns, kw...)
|
annotate!{T<:Tuple}(plt::PlotOrSubplot, anns::AVec{T}; kw...) = plot!(plt; annotation = anns, kw...)
|
||||||
xflip!(plt::PlotOrSubplot, flip::Bool = true; kw...) = plot!(plt; xflip = flip, kw...)
|
xflip!(plt::PlotOrSubplot, flip::Bool = true; kw...) = plot!(plt; xflip = flip, kw...)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
|
"Represents an animation object"
|
||||||
immutable Animation
|
immutable Animation
|
||||||
dir::String
|
dir::String
|
||||||
frames::Vector{String}
|
frames::Vector{String}
|
||||||
@ -9,6 +9,11 @@ function Animation()
|
|||||||
Animation(tmpdir, String[])
|
Animation(tmpdir, String[])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
frame(animation[, plot])
|
||||||
|
|
||||||
|
Add a plot (the current plot if not specified) to an existing animation
|
||||||
|
"""
|
||||||
function frame{P<:AbstractPlot}(anim::Animation, plt::P=current())
|
function frame{P<:AbstractPlot}(anim::Animation, plt::P=current())
|
||||||
i = length(anim.frames) + 1
|
i = length(anim.frames) + 1
|
||||||
filename = @sprintf("%06d.png", i)
|
filename = @sprintf("%06d.png", i)
|
||||||
@ -81,7 +86,7 @@ function buildanimation(animdir::AbstractString, fn::AbstractString;
|
|||||||
catch err
|
catch err
|
||||||
warn("""Tried to create gif using convert (ImageMagick), but got error: $err
|
warn("""Tried to create gif using convert (ImageMagick), but got error: $err
|
||||||
ImageMagick can be installed by executing `Pkg.add("ImageMagick")`.
|
ImageMagick can be installed by executing `Pkg.add("ImageMagick")`.
|
||||||
You may also need to install the imagemagick c++ library through your operating system.
|
You may also need to install the imagemagick c++ library through your operating system.
|
||||||
Will try ffmpeg, but it's lower quality...)""")
|
Will try ffmpeg, but it's lower quality...)""")
|
||||||
|
|
||||||
# low quality
|
# low quality
|
||||||
|
|||||||
@ -21,7 +21,7 @@ const _arg_desc = KW(
|
|||||||
:markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)",
|
: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`.",
|
: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.",
|
: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. 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)`",
|
: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?",
|
:smooth => "Bool. Add a regression line?",
|
||||||
:group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.",
|
:group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.",
|
||||||
:x => "Various. Input data. First Dimension",
|
:x => "Various. Input data. First Dimension",
|
||||||
@ -40,7 +40,7 @@ const _arg_desc = KW(
|
|||||||
:ribbon => "Number or AbstractVector. Creates a fillrange around the data points.",
|
:ribbon => "Number or AbstractVector. Creates a fillrange around the data points.",
|
||||||
:quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.",
|
:quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.",
|
||||||
:arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.",
|
:arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.",
|
||||||
:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a PDF with integral of 1) and :density (only normalize in respect to bin sizes).",
|
:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).",
|
||||||
:weights => "AbstractVector. Used in histogram types for weighted counts.",
|
:weights => "AbstractVector. Used in histogram types for weighted counts.",
|
||||||
:contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.",
|
:contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.",
|
||||||
:match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.",
|
:match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.",
|
||||||
@ -76,7 +76,6 @@ const _arg_desc = KW(
|
|||||||
:background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).",
|
:background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).",
|
||||||
:foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.",
|
:foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.",
|
||||||
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
|
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
|
||||||
:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.",
|
|
||||||
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
|
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
|
||||||
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
|
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
|
||||||
:legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)",
|
:legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)",
|
||||||
@ -84,7 +83,6 @@ const _arg_desc = KW(
|
|||||||
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
|
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
|
||||||
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
|
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
|
||||||
:legendfont => "Font. Font of legend items.",
|
:legendfont => "Font. Font of legend items.",
|
||||||
:grid => "Bool. Show the grid lines?",
|
|
||||||
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
|
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
|
||||||
:projection => "Symbol or String. '3d' or 'polar'",
|
:projection => "Symbol or String. '3d' or 'polar'",
|
||||||
:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `apect_ratio` x-units.",
|
:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `apect_ratio` x-units.",
|
||||||
@ -95,6 +93,7 @@ const _arg_desc = KW(
|
|||||||
:bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.",
|
:bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.",
|
||||||
:subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.",
|
:subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.",
|
||||||
:colorbar_title => "String. Title of colorbar.",
|
:colorbar_title => "String. Title of colorbar.",
|
||||||
|
:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)",
|
||||||
|
|
||||||
# axis args
|
# axis args
|
||||||
:guide => "String. Axis guide (label).",
|
:guide => "String. Axis guide (label).",
|
||||||
@ -111,5 +110,9 @@ const _arg_desc = KW(
|
|||||||
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
|
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
|
||||||
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
|
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
|
||||||
:mirror => "Bool. Switch the side of the tick labels (right or top).",
|
:mirror => "Bool. Switch the side of the tick labels (right or top).",
|
||||||
|
:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`",
|
||||||
|
:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.",
|
||||||
|
: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)",
|
||||||
)
|
)
|
||||||
|
|||||||
127
src/args.jl
127
src/args.jl
@ -80,9 +80,13 @@ const _typeAliases = Dict{Symbol,Symbol}(
|
|||||||
|
|
||||||
add_non_underscore_aliases!(_typeAliases)
|
add_non_underscore_aliases!(_typeAliases)
|
||||||
|
|
||||||
like_histogram(seriestype::Symbol) = seriestype in (:histogram, :barhist, :barbins)
|
const _histogram_like = [:histogram, :barhist, :barbins]
|
||||||
like_line(seriestype::Symbol) = seriestype in (:line, :path, :steppre, :steppost)
|
const _line_like = [:line, :path, :steppre, :steppost]
|
||||||
like_surface(seriestype::Symbol) = seriestype in (:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image)
|
const _surface_like = [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image]
|
||||||
|
|
||||||
|
like_histogram(seriestype::Symbol) = seriestype in _histogram_like
|
||||||
|
like_line(seriestype::Symbol) = seriestype in _line_like
|
||||||
|
like_surface(seriestype::Symbol) = seriestype in _surface_like
|
||||||
|
|
||||||
is3d(seriestype::Symbol) = seriestype in _3dTypes
|
is3d(seriestype::Symbol) = seriestype in _3dTypes
|
||||||
is3d(series::Series) = is3d(series.d)
|
is3d(series::Series) = is3d(series.d)
|
||||||
@ -163,6 +167,32 @@ const _scaleAliases = Dict{Symbol,Symbol}(
|
|||||||
:log => :log10,
|
:log => :log10,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const _allGridSyms = [:x, :y, :z,
|
||||||
|
:xy, :xz, :yx, :yz, :zx, :zy,
|
||||||
|
:xyz, :xzy, :yxz, :yzx, :zxy, :zyx,
|
||||||
|
:all, :both, :on,
|
||||||
|
:none, :off,]
|
||||||
|
const _allGridArgs = [_allGridSyms; string.(_allGridSyms); nothing]
|
||||||
|
hasgrid(arg::Void, letter) = false
|
||||||
|
hasgrid(arg::Bool, letter) = arg
|
||||||
|
function hasgrid(arg::Symbol, letter)
|
||||||
|
if arg in _allGridSyms
|
||||||
|
arg in (:all, :both, :on) || contains(string(arg), string(letter))
|
||||||
|
else
|
||||||
|
warn("Unknown grid argument $arg; $(Symbol(letter, :grid)) was set to `true` instead.")
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter)
|
||||||
|
|
||||||
|
const _allFramestyles = [:box, :semi, :axes, :grid, :none]
|
||||||
|
const _framestyleAliases = Dict{Symbol, Symbol}(
|
||||||
|
:frame => :box,
|
||||||
|
:border => :box,
|
||||||
|
:on => :box,
|
||||||
|
:transparent => :semi,
|
||||||
|
:semitransparent => :semi,
|
||||||
|
)
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
const _series_defaults = KW(
|
const _series_defaults = KW(
|
||||||
@ -172,7 +202,7 @@ const _series_defaults = KW(
|
|||||||
:seriestype => :path,
|
:seriestype => :path,
|
||||||
:linestyle => :solid,
|
:linestyle => :solid,
|
||||||
:linewidth => :auto,
|
:linewidth => :auto,
|
||||||
:linecolor => :match,
|
:linecolor => :auto,
|
||||||
:linealpha => nothing,
|
:linealpha => nothing,
|
||||||
:fillrange => nothing, # ribbons, areas, etc
|
:fillrange => nothing, # ribbons, areas, etc
|
||||||
:fillcolor => :match,
|
:fillcolor => :match,
|
||||||
@ -248,7 +278,6 @@ const _subplot_defaults = KW(
|
|||||||
:background_color_inside => :match, # background inside grid
|
:background_color_inside => :match, # background inside grid
|
||||||
:foreground_color_subplot => :match, # default for other fg colors... match takes plot default
|
:foreground_color_subplot => :match, # default for other fg colors... match takes plot default
|
||||||
:foreground_color_legend => :match, # foreground of legend
|
:foreground_color_legend => :match, # foreground of legend
|
||||||
:foreground_color_grid => :match, # grid color
|
|
||||||
:foreground_color_title => :match, # title color
|
:foreground_color_title => :match, # title color
|
||||||
:color_palette => :auto,
|
:color_palette => :auto,
|
||||||
:legend => :best,
|
:legend => :best,
|
||||||
@ -256,7 +285,6 @@ const _subplot_defaults = KW(
|
|||||||
:colorbar => :legend,
|
:colorbar => :legend,
|
||||||
:clims => :auto,
|
:clims => :auto,
|
||||||
:legendfont => font(8),
|
:legendfont => font(8),
|
||||||
:grid => true,
|
|
||||||
:annotations => [], # annotation tuples... list of (x,y,annotation)
|
:annotations => [], # annotation tuples... list of (x,y,annotation)
|
||||||
:projection => :none, # can also be :polar or :3d
|
:projection => :none, # can also be :polar or :3d
|
||||||
:aspect_ratio => :none, # choose from :none or :equal
|
:aspect_ratio => :none, # choose from :none or :equal
|
||||||
@ -267,6 +295,7 @@ const _subplot_defaults = KW(
|
|||||||
:bottom_margin => :match,
|
:bottom_margin => :match,
|
||||||
:subplot_index => -1,
|
:subplot_index => -1,
|
||||||
:colorbar_title => "",
|
:colorbar_title => "",
|
||||||
|
:framestyle => :axes,
|
||||||
)
|
)
|
||||||
|
|
||||||
const _axis_defaults = KW(
|
const _axis_defaults = KW(
|
||||||
@ -286,6 +315,11 @@ const _axis_defaults = KW(
|
|||||||
:discrete_values => [],
|
:discrete_values => [],
|
||||||
:formatter => :auto,
|
:formatter => :auto,
|
||||||
:mirror => false,
|
:mirror => false,
|
||||||
|
:grid => true,
|
||||||
|
:foreground_color_grid => :match, # grid color
|
||||||
|
:gridalpha => 0.1,
|
||||||
|
:gridstyle => :solid,
|
||||||
|
:gridlinewidth => 0.5,
|
||||||
)
|
)
|
||||||
|
|
||||||
const _suppress_warnings = Set{Symbol}([
|
const _suppress_warnings = Set{Symbol}([
|
||||||
@ -403,7 +437,7 @@ add_aliases(:foreground_color_title, :fg_title, :fgtitle, :fgcolor_title, :fg_co
|
|||||||
add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis,
|
add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis,
|
||||||
:foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor)
|
:foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor)
|
||||||
add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border,
|
add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border,
|
||||||
:foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor, :border)
|
:foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor)
|
||||||
add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text,
|
add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text,
|
||||||
:foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor)
|
:foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor)
|
||||||
add_aliases(:foreground_color_guide, :fg_guide, :fgguide, :fgcolor_guide, :fg_color_guide, :foreground_guide,
|
add_aliases(:foreground_color_guide, :fg_guide, :fgguide, :fgcolor_guide, :fg_color_guide, :foreground_guide,
|
||||||
@ -415,6 +449,7 @@ add_aliases(:linealpha, :la, :lalpha, :lα, :lineopacity, :lopacity)
|
|||||||
add_aliases(:markeralpha, :ma, :malpha, :mα, :markeropacity, :mopacity)
|
add_aliases(:markeralpha, :ma, :malpha, :mα, :markeropacity, :mopacity)
|
||||||
add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity)
|
add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity)
|
||||||
add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity)
|
add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity)
|
||||||
|
add_aliases(:gridalpha, :ga, :galpha, :gα, :gridopacity, :gopacity)
|
||||||
|
|
||||||
# series attributes
|
# series attributes
|
||||||
add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt)
|
add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt)
|
||||||
@ -471,6 +506,9 @@ add_aliases(:html_output_format, :format, :fmt, :html_format)
|
|||||||
add_aliases(:orientation, :direction, :dir)
|
add_aliases(:orientation, :direction, :dir)
|
||||||
add_aliases(:inset_subplots, :inset, :floating)
|
add_aliases(:inset_subplots, :inset, :floating)
|
||||||
add_aliases(:stride, :wirefame_stride, :surface_stride, :surf_str, :str)
|
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(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border)
|
||||||
|
|
||||||
|
|
||||||
# add all pluralized forms to the _keyAliases dict
|
# add all pluralized forms to the _keyAliases dict
|
||||||
@ -490,7 +528,6 @@ end
|
|||||||
`default(; kw...)` will set the current default value for each key/value pair
|
`default(; kw...)` will set the current default value for each key/value pair
|
||||||
`default(d, key)` returns the key from d if it exists, otherwise `default(key)`
|
`default(d, key)` returns the key from d if it exists, otherwise `default(key)`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
function default(k::Symbol)
|
function default(k::Symbol)
|
||||||
k = get(_keyAliases, k, k)
|
k = get(_keyAliases, k, k)
|
||||||
for defaults in _all_defaults
|
for defaults in _all_defaults
|
||||||
@ -647,6 +684,36 @@ function processFillArg(d::KW, arg)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function processGridArg!(d::KW, arg, letter)
|
||||||
|
if arg in _allGridArgs || isa(arg, Bool)
|
||||||
|
d[Symbol(letter, :grid)] = hasgrid(arg, letter)
|
||||||
|
|
||||||
|
elseif allStyles(arg)
|
||||||
|
d[Symbol(letter, :gridstyle)] = arg
|
||||||
|
|
||||||
|
elseif typeof(arg) <: Stroke
|
||||||
|
arg.width == nothing || (d[Symbol(letter, :gridlinewidth)] = arg.width)
|
||||||
|
arg.color == nothing || (d[Symbol(letter, :foreground_color_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color))
|
||||||
|
arg.alpha == nothing || (d[Symbol(letter, :gridalpha)] = arg.alpha)
|
||||||
|
arg.style == nothing || (d[Symbol(letter, :gridstyle)] = arg.style)
|
||||||
|
|
||||||
|
# linealpha
|
||||||
|
elseif allAlphas(arg)
|
||||||
|
d[Symbol(letter, :gridalpha)] = arg
|
||||||
|
|
||||||
|
# linewidth
|
||||||
|
elseif allReals(arg)
|
||||||
|
d[Symbol(letter, :gridlinewidth)] = arg
|
||||||
|
|
||||||
|
# color
|
||||||
|
elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid))
|
||||||
|
warn("Skipped grid arg $arg.")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
_replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape)
|
_replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape)
|
||||||
_replace_markershape(shapes::AVec) = map(_replace_markershape, shapes)
|
_replace_markershape(shapes::AVec) = map(_replace_markershape, shapes)
|
||||||
_replace_markershape(shape) = shape
|
_replace_markershape(shape) = shape
|
||||||
@ -668,6 +735,7 @@ function preprocessArgs!(d::KW)
|
|||||||
if haskey(d, :axis) && d[:axis] in (:none, nothing, false)
|
if haskey(d, :axis) && d[:axis] in (:none, nothing, false)
|
||||||
d[:ticks] = nothing
|
d[:ticks] = nothing
|
||||||
d[:foreground_color_border] = RGBA(0,0,0,0)
|
d[:foreground_color_border] = RGBA(0,0,0,0)
|
||||||
|
d[:foreground_color_axis] = RGBA(0,0,0,0)
|
||||||
d[:grid] = false
|
d[:grid] = false
|
||||||
delete!(d, :axis)
|
delete!(d, :axis)
|
||||||
end
|
end
|
||||||
@ -690,6 +758,22 @@ function preprocessArgs!(d::KW)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# handle grid args common to all axes
|
||||||
|
args = pop!(d, :grid, ())
|
||||||
|
for arg in wraptuple(args)
|
||||||
|
for letter in (:x, :y, :z)
|
||||||
|
processGridArg!(d, arg, letter)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# handle individual axes grid args
|
||||||
|
for letter in (:x, :y, :z)
|
||||||
|
gridsym = Symbol(letter, :grid)
|
||||||
|
args = pop!(d, gridsym, ())
|
||||||
|
for arg in wraptuple(args)
|
||||||
|
processGridArg!(d, arg, letter)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# handle line args
|
# handle line args
|
||||||
for arg in wraptuple(pop!(d, :line, ()))
|
for arg in wraptuple(pop!(d, :line, ()))
|
||||||
processLineArg(d, arg)
|
processLineArg(d, arg)
|
||||||
@ -754,6 +838,11 @@ function preprocessArgs!(d::KW)
|
|||||||
d[:colorbar] = convertLegendValue(d[:colorbar])
|
d[:colorbar] = convertLegendValue(d[:colorbar])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# framestyle
|
||||||
|
if haskey(d, :framestyle) && haskey(_framestyleAliases, d[:framestyle])
|
||||||
|
d[:framestyle] = _framestyleAliases[d[:framestyle]]
|
||||||
|
end
|
||||||
|
|
||||||
# warnings for moved recipes
|
# warnings for moved recipes
|
||||||
st = get(d, :seriestype, :path)
|
st = get(d, :seriestype, :path)
|
||||||
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots)
|
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots)
|
||||||
@ -773,21 +862,29 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# this is when given a vector-type of values to group by
|
# this is when given a vector-type of values to group by
|
||||||
function extractGroupArgs(v::AVec, args...)
|
function extractGroupArgs(v::AVec, args...; legendEntry = string)
|
||||||
groupLabels = sort(collect(unique(v)))
|
groupLabels = sort(collect(unique(v)))
|
||||||
n = length(groupLabels)
|
n = length(groupLabels)
|
||||||
if n > 100
|
if n > 100
|
||||||
warn("You created n=$n groups... Is that intended?")
|
warn("You created n=$n groups... Is that intended?")
|
||||||
end
|
end
|
||||||
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
|
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
|
||||||
GroupBy(map(string, groupLabels), groupIds)
|
GroupBy(map(legendEntry, groupLabels), groupIds)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
legendEntryFromTuple(ns::Tuple) = string(("$n " for n in ns)...)
|
||||||
|
|
||||||
|
# this is when given a tuple of vectors of values to group by
|
||||||
|
function extractGroupArgs(vs::Tuple, args...)
|
||||||
|
(vs == ()) && return GroupBy([""], [1:size(args[1],1)])
|
||||||
|
v = collect(zip(vs...))
|
||||||
|
extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple)
|
||||||
|
end
|
||||||
|
|
||||||
# expecting a mapping of "group label" to "group indices"
|
# expecting a mapping of "group label" to "group indices"
|
||||||
function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...)
|
function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...)
|
||||||
groupLabels = sortedkeys(idxmap)
|
groupLabels = sortedkeys(idxmap)
|
||||||
groupIds = VecI[collect(idxmap[k]) for k in groupLabels]
|
groupIds = Vector{Int}[collect(idxmap[k]) for k in groupLabels]
|
||||||
GroupBy(groupLabels, groupIds)
|
GroupBy(groupLabels, groupIds)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -945,7 +1042,6 @@ const _match_map = KW(
|
|||||||
:background_color_legend => :background_color_subplot,
|
:background_color_legend => :background_color_subplot,
|
||||||
:background_color_inside => :background_color_subplot,
|
:background_color_inside => :background_color_subplot,
|
||||||
:foreground_color_legend => :foreground_color_subplot,
|
:foreground_color_legend => :foreground_color_subplot,
|
||||||
:foreground_color_grid => :foreground_color_subplot,
|
|
||||||
:foreground_color_title => :foreground_color_subplot,
|
:foreground_color_title => :foreground_color_subplot,
|
||||||
:left_margin => :margin,
|
:left_margin => :margin,
|
||||||
:top_margin => :margin,
|
:top_margin => :margin,
|
||||||
@ -959,6 +1055,7 @@ const _match_map2 = KW(
|
|||||||
:foreground_color_subplot => :foreground_color,
|
:foreground_color_subplot => :foreground_color,
|
||||||
:foreground_color_axis => :foreground_color_subplot,
|
:foreground_color_axis => :foreground_color_subplot,
|
||||||
:foreground_color_border => :foreground_color_subplot,
|
:foreground_color_border => :foreground_color_subplot,
|
||||||
|
:foreground_color_grid => :foreground_color_subplot,
|
||||||
:foreground_color_guide => :foreground_color_subplot,
|
:foreground_color_guide => :foreground_color_subplot,
|
||||||
:foreground_color_text => :foreground_color_subplot,
|
:foreground_color_text => :foreground_color_subplot,
|
||||||
)
|
)
|
||||||
@ -1093,7 +1190,6 @@ function _update_subplot_colors(sp::Subplot)
|
|||||||
# foreground colors
|
# foreground colors
|
||||||
color_or_nothing!(sp.attr, :foreground_color_subplot)
|
color_or_nothing!(sp.attr, :foreground_color_subplot)
|
||||||
color_or_nothing!(sp.attr, :foreground_color_legend)
|
color_or_nothing!(sp.attr, :foreground_color_legend)
|
||||||
color_or_nothing!(sp.attr, :foreground_color_grid)
|
|
||||||
color_or_nothing!(sp.attr, :foreground_color_title)
|
color_or_nothing!(sp.attr, :foreground_color_title)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -1145,6 +1241,7 @@ function _update_axis_colors(axis::Axis)
|
|||||||
color_or_nothing!(axis.d, :foreground_color_border)
|
color_or_nothing!(axis.d, :foreground_color_border)
|
||||||
color_or_nothing!(axis.d, :foreground_color_guide)
|
color_or_nothing!(axis.d, :foreground_color_guide)
|
||||||
color_or_nothing!(axis.d, :foreground_color_text)
|
color_or_nothing!(axis.d, :foreground_color_text)
|
||||||
|
color_or_nothing!(axis.d, :foreground_color_grid)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1250,12 +1347,14 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
|||||||
# update other colors
|
# update other colors
|
||||||
for s in (:line, :marker, :fill)
|
for s in (:line, :marker, :fill)
|
||||||
csym, asym = Symbol(s,:color), Symbol(s,:alpha)
|
csym, asym = Symbol(s,:color), Symbol(s,:alpha)
|
||||||
d[csym] = if d[csym] == :match
|
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]
|
sp[:foreground_color_subplot]
|
||||||
else
|
else
|
||||||
d[:seriescolor]
|
d[:seriescolor]
|
||||||
end, d[asym])
|
end, d[asym])
|
||||||
|
elseif d[csym] == :match
|
||||||
|
plot_color(d[:seriescolor], d[asym])
|
||||||
else
|
else
|
||||||
getSeriesRGBColor(d[csym], d[asym], sp, plotIndex)
|
getSeriesRGBColor(d[csym], d[asym], sp, plotIndex)
|
||||||
end
|
end
|
||||||
|
|||||||
94
src/axes.jl
94
src/axes.jl
@ -181,15 +181,27 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# get a list of well-laid-out ticks
|
# get a list of well-laid-out ticks
|
||||||
scaled_ticks = if ticks == nothing
|
if ticks == nothing
|
||||||
optimize_ticks(
|
scaled_ticks = optimize_ticks(
|
||||||
sf(amin),
|
sf(amin),
|
||||||
sf(amax);
|
sf(amax);
|
||||||
k_min = 5, # minimum number of ticks
|
k_min = 4, # minimum number of ticks
|
||||||
k_max = 8, # maximum number of ticks
|
k_max = 8, # maximum number of ticks
|
||||||
)[1]
|
)[1]
|
||||||
|
elseif typeof(ticks) <: Int
|
||||||
|
scaled_ticks, viewmin, viewmax = optimize_ticks(
|
||||||
|
sf(amin),
|
||||||
|
sf(amax);
|
||||||
|
k_min = ticks, # minimum number of ticks
|
||||||
|
k_max = ticks, # maximum number of ticks
|
||||||
|
k_ideal = ticks,
|
||||||
|
# `strict_span = false` rewards cases where the span of the
|
||||||
|
# chosen ticks is not too much bigger than amin - amax:
|
||||||
|
strict_span = false,
|
||||||
|
)
|
||||||
|
axis[:lims] = map(invscalefunc(scale), (viewmin, viewmax))
|
||||||
else
|
else
|
||||||
map(sf, filter(t -> amin <= t <= amax, ticks))
|
scaled_ticks = map(sf, (filter(t -> amin <= t <= amax, ticks)))
|
||||||
end
|
end
|
||||||
unscaled_ticks = map(invscalefunc(scale), scaled_ticks)
|
unscaled_ticks = map(invscalefunc(scale), scaled_ticks)
|
||||||
|
|
||||||
@ -216,7 +228,7 @@ end
|
|||||||
|
|
||||||
# return (continuous_values, discrete_values) for the ticks on this axis
|
# return (continuous_values, discrete_values) for the ticks on this axis
|
||||||
function get_ticks(axis::Axis)
|
function get_ticks(axis::Axis)
|
||||||
ticks = axis[:ticks]
|
ticks = _transform_ticks(axis[:ticks])
|
||||||
ticks in (nothing, false) && return nothing
|
ticks in (nothing, false) && return nothing
|
||||||
|
|
||||||
dvals = axis[:discrete_values]
|
dvals = axis[:discrete_values]
|
||||||
@ -226,7 +238,7 @@ function get_ticks(axis::Axis)
|
|||||||
elseif ticks == :auto
|
elseif ticks == :auto
|
||||||
# compute optimal ticks and labels
|
# compute optimal ticks and labels
|
||||||
optimal_ticks_and_labels(axis)
|
optimal_ticks_and_labels(axis)
|
||||||
elseif typeof(ticks) <: AVec
|
elseif typeof(ticks) <: Union{AVec, Int}
|
||||||
# override ticks, but get the labels
|
# override ticks, but get the labels
|
||||||
optimal_ticks_and_labels(axis, ticks)
|
optimal_ticks_and_labels(axis, ticks)
|
||||||
elseif typeof(ticks) <: NTuple{2, Any}
|
elseif typeof(ticks) <: NTuple{2, Any}
|
||||||
@ -246,6 +258,10 @@ function get_ticks(axis::Axis)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
_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])
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@ -490,38 +506,46 @@ function axis_drawing_info(sp::Subplot)
|
|||||||
ymin, ymax = axis_limits(yaxis)
|
ymin, ymax = axis_limits(yaxis)
|
||||||
xticks = get_ticks(xaxis)
|
xticks = get_ticks(xaxis)
|
||||||
yticks = get_ticks(yaxis)
|
yticks = get_ticks(yaxis)
|
||||||
spine_segs = Segments(2)
|
xaxis_segs = Segments(2)
|
||||||
grid_segs = Segments(2)
|
yaxis_segs = Segments(2)
|
||||||
|
xgrid_segs = Segments(2)
|
||||||
|
ygrid_segs = Segments(2)
|
||||||
|
xborder_segs = Segments(2)
|
||||||
|
yborder_segs = Segments(2)
|
||||||
|
|
||||||
if !(xaxis[:ticks] in (nothing, false))
|
if !(sp[:framestyle] == :none)
|
||||||
f = scalefunc(yaxis[:scale])
|
# xaxis
|
||||||
invf = invscalefunc(yaxis[:scale])
|
sp[:framestyle] == :grid || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis
|
||||||
t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin)))
|
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine
|
||||||
t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin)))
|
if !(xaxis[:ticks] in (nothing, false))
|
||||||
|
f = scalefunc(yaxis[:scale])
|
||||||
|
invf = invscalefunc(yaxis[:scale])
|
||||||
|
t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin)))
|
||||||
|
t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin)))
|
||||||
|
|
||||||
push!(spine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine
|
for xtick in xticks[1]
|
||||||
# push!(spine_segs, (xmin,ymax), (xmax,ymax)) # top spine
|
push!(xaxis_segs, (xtick, ymin), (xtick, t1)) # bottom tick
|
||||||
for xtick in xticks[1]
|
# sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick
|
||||||
push!(spine_segs, (xtick, ymin), (xtick, t1)) # bottom tick
|
xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid
|
||||||
push!(grid_segs, (xtick, t1), (xtick, t2)) # vertical grid
|
end
|
||||||
# push!(spine_segs, (xtick, ymax), (xtick, t2)) # top tick
|
end
|
||||||
|
|
||||||
|
# yaxis
|
||||||
|
sp[:framestyle] == :grid || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis
|
||||||
|
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine
|
||||||
|
if !(yaxis[:ticks] in (nothing, false))
|
||||||
|
f = scalefunc(xaxis[:scale])
|
||||||
|
invf = invscalefunc(xaxis[:scale])
|
||||||
|
t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin)))
|
||||||
|
t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin)))
|
||||||
|
|
||||||
|
for ytick in yticks[1]
|
||||||
|
push!(yaxis_segs, (xmin, ytick), (t1, ytick)) # left tick
|
||||||
|
# sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick
|
||||||
|
yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !(yaxis[:ticks] in (nothing, false))
|
xticks, yticks, xaxis_segs, yaxis_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs
|
||||||
f = scalefunc(xaxis[:scale])
|
|
||||||
invf = invscalefunc(xaxis[:scale])
|
|
||||||
t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin)))
|
|
||||||
t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin)))
|
|
||||||
|
|
||||||
push!(spine_segs, (xmin,ymin), (xmin,ymax)) # left spine
|
|
||||||
# push!(spine_segs, (xmax,ymin), (xmax,ymax)) # right spine
|
|
||||||
for ytick in yticks[1]
|
|
||||||
push!(spine_segs, (xmin, ytick), (t1, ytick)) # left tick
|
|
||||||
push!(grid_segs, (t1, ytick), (t2, ytick)) # horizontal grid
|
|
||||||
# push!(spine_segs, (xmax, ytick), (t2, ytick)) # right tick
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
xticks, yticks, spine_segs, grid_segs
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -6,7 +6,10 @@ const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none)
|
|||||||
const _backends = Symbol[]
|
const _backends = Symbol[]
|
||||||
const _initialized_backends = Set{Symbol}()
|
const _initialized_backends = Set{Symbol}()
|
||||||
|
|
||||||
|
"Returns a list of supported backends"
|
||||||
backends() = _backends
|
backends() = _backends
|
||||||
|
|
||||||
|
"Returns the name of the current backend"
|
||||||
backend_name() = CURRENT_BACKEND.sym
|
backend_name() = CURRENT_BACKEND.sym
|
||||||
_backend_instance(sym::Symbol) = haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym")
|
_backend_instance(sym::Symbol) = haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym")
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,8 @@ const _glvisualize_attr = merge_with_base_supported([
|
|||||||
:window_title,
|
:window_title,
|
||||||
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend, :colorbar,
|
:grid, :gridalpha, :gridstyle, :gridlinewidth,
|
||||||
|
:legend, :colorbar,
|
||||||
:marker_z,
|
:marker_z,
|
||||||
:line_z,
|
:line_z,
|
||||||
:levels,
|
:levels,
|
||||||
@ -38,7 +39,8 @@ const _glvisualize_attr = merge_with_base_supported([
|
|||||||
:clims,
|
:clims,
|
||||||
:inset_subplots,
|
:inset_subplots,
|
||||||
:dpi,
|
:dpi,
|
||||||
:hover
|
:hover,
|
||||||
|
:framestyle,
|
||||||
])
|
])
|
||||||
const _glvisualize_seriestype = [
|
const _glvisualize_seriestype = [
|
||||||
:path, :shape,
|
:path, :shape,
|
||||||
@ -676,17 +678,29 @@ function text_model(font, pivot)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area)
|
function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area)
|
||||||
xticks, yticks, spine_segs, grid_segs = Plots.axis_drawing_info(sp)
|
xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp)
|
||||||
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
|
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
|
||||||
|
|
||||||
c = Colors.color(Plots.gl_color(sp[:foreground_color_grid]))
|
xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid]))
|
||||||
|
ygc = Colors.color(Plots.gl_color(yaxis[:foreground_color_grid]))
|
||||||
axis_vis = []
|
axis_vis = []
|
||||||
if sp[:grid]
|
if xaxis[:grid]
|
||||||
grid = draw_grid_lines(sp, grid_segs, 1f0, :dot, model, RGBA(c, 0.3f0))
|
grid = draw_grid_lines(sp, xgrid_segs, xaxis[:gridlinewidth], xaxis[:gridstyle], model, RGBA(xgc, xaxis[:gridalpha]))
|
||||||
push!(axis_vis, grid)
|
push!(axis_vis, grid)
|
||||||
end
|
end
|
||||||
if alpha(xaxis[:foreground_color_border]) > 0
|
if yaxis[:grid]
|
||||||
spine = draw_grid_lines(sp, spine_segs, 1f0, :solid, model, RGBA(c, 1.0f0))
|
grid = draw_grid_lines(sp, ygrid_segs, yaxis[:gridlinewidth], yaxis[:gridstyle], model, RGBA(ygc, yaxis[:gridalpha]))
|
||||||
|
push!(axis_vis, grid)
|
||||||
|
end
|
||||||
|
|
||||||
|
xac = Colors.color(Plots.gl_color(xaxis[:foreground_color_axis]))
|
||||||
|
yac = Colors.color(Plots.gl_color(yaxis[:foreground_color_axis]))
|
||||||
|
if alpha(xaxis[:foreground_color_axis]) > 0
|
||||||
|
spine = draw_grid_lines(sp, xspine_segs, 1f0, :solid, model, RGBA(xac, 1.0f0))
|
||||||
|
push!(axis_vis, spine)
|
||||||
|
end
|
||||||
|
if alpha(yaxis[:foreground_color_axis]) > 0
|
||||||
|
spine = draw_grid_lines(sp, yspine_segs, 1f0, :solid, model, RGBA(yac, 1.0f0))
|
||||||
push!(axis_vis, spine)
|
push!(axis_vis, spine)
|
||||||
end
|
end
|
||||||
fcolor = Plots.gl_color(xaxis[:foreground_color_axis])
|
fcolor = Plots.gl_color(xaxis[:foreground_color_axis])
|
||||||
@ -694,7 +708,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are
|
|||||||
xlim = Plots.axis_limits(xaxis)
|
xlim = Plots.axis_limits(xaxis)
|
||||||
ylim = Plots.axis_limits(yaxis)
|
ylim = Plots.axis_limits(yaxis)
|
||||||
|
|
||||||
if !(xaxis[:ticks] in (nothing, false, :none))
|
if !(xaxis[:ticks] in (nothing, false, :none)) && !(sp[:framestyle] == :none)
|
||||||
ticklabels = map(model) do m
|
ticklabels = map(model) do m
|
||||||
mirror = xaxis[:mirror]
|
mirror = xaxis[:mirror]
|
||||||
t, positions, offsets = draw_ticks(xaxis, xticks, true, ylim, m)
|
t, positions, offsets = draw_ticks(xaxis, xticks, true, ylim, m)
|
||||||
@ -714,6 +728,15 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are
|
|||||||
push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args))
|
push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
xbc = Colors.color(Plots.gl_color(xaxis[:foreground_color_border]))
|
||||||
|
ybc = Colors.color(Plots.gl_color(yaxis[:foreground_color_border]))
|
||||||
|
intensity = sp[:framestyle] == :semi ? 0.5f0 : 1.0f0
|
||||||
|
if sp[:framestyle] in (:box, :semi)
|
||||||
|
xborder = draw_grid_lines(sp, xborder_segs, intensity, :solid, model, RGBA(xbc, intensity))
|
||||||
|
yborder = draw_grid_lines(sp, yborder_segs, intensity, :solid, model, RGBA(ybc, intensity))
|
||||||
|
push!(axis_vis, xborder, yborder)
|
||||||
|
end
|
||||||
|
|
||||||
area_w = GeometryTypes.widths(area)
|
area_w = GeometryTypes.widths(area)
|
||||||
if sp[:title] != ""
|
if sp[:title] != ""
|
||||||
tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title])
|
tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title])
|
||||||
|
|||||||
@ -20,7 +20,8 @@ const _gr_attr = merge_with_base_supported([
|
|||||||
:title, :window_title,
|
:title, :window_title,
|
||||||
:guide, :lims, :ticks, :scale, :flip,
|
:guide, :lims, :ticks, :scale, :flip,
|
||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend, :legendtitle, :colorbar,
|
:grid, :gridalpha, :gridstyle, :gridlinewidth,
|
||||||
|
:legend, :legendtitle, :colorbar,
|
||||||
:marker_z, :levels,
|
:marker_z, :levels,
|
||||||
:ribbon, :quiver,
|
:ribbon, :quiver,
|
||||||
:orientation,
|
:orientation,
|
||||||
@ -31,6 +32,7 @@ const _gr_attr = merge_with_base_supported([
|
|||||||
:inset_subplots,
|
:inset_subplots,
|
||||||
:bar_width,
|
:bar_width,
|
||||||
:arrow,
|
:arrow,
|
||||||
|
:framestyle,
|
||||||
])
|
])
|
||||||
const _gr_seriestype = [
|
const _gr_seriestype = [
|
||||||
:path, :scatter,
|
:path, :scatter,
|
||||||
@ -325,7 +327,10 @@ function gr_draw_markers(series::Series, x, y, msize, mz)
|
|||||||
cfuncind(ci)
|
cfuncind(ci)
|
||||||
GR.settransparency(_gr_gradient_alpha[ci-999])
|
GR.settransparency(_gr_gradient_alpha[ci-999])
|
||||||
end
|
end
|
||||||
gr_draw_marker(x[i], y[i], msi, shape)
|
# don't draw filled area if marker shape is 1D
|
||||||
|
if !(shape in (:hline, :vline, :+, :x))
|
||||||
|
gr_draw_marker(x[i], y[i], msi, shape)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -336,6 +341,7 @@ function gr_draw_markers(series::Series, x, y)
|
|||||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||||
gr_draw_markers(series, x, y, series[:markersize], mz)
|
gr_draw_markers(series, x, y, series[:markersize], mz)
|
||||||
if mz != nothing
|
if mz != nothing
|
||||||
|
GR.setscale(0)
|
||||||
gr_colorbar(series[:subplot])
|
gr_colorbar(series[:subplot])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -537,40 +543,91 @@ function gr_display(plt::Plot)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function gr_set_xticks_font(sp)
|
||||||
|
flip = sp[:yaxis][:flip]
|
||||||
|
mirror = sp[:xaxis][:mirror]
|
||||||
|
gr_set_font(sp[:xaxis][:tickfont],
|
||||||
|
halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2],
|
||||||
|
valign = (mirror ? :bottom : :top),
|
||||||
|
color = sp[:xaxis][:foreground_color_axis],
|
||||||
|
rotation = sp[:xaxis][:rotation])
|
||||||
|
return flip, mirror
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function gr_set_yticks_font(sp)
|
||||||
|
flip = sp[:xaxis][:flip]
|
||||||
|
mirror = sp[:yaxis][:mirror]
|
||||||
|
gr_set_font(sp[:yaxis][:tickfont],
|
||||||
|
halign = (mirror ? :left : :right),
|
||||||
|
valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2],
|
||||||
|
color = sp[:yaxis][:foreground_color_axis],
|
||||||
|
rotation = sp[:yaxis][:rotation])
|
||||||
|
return flip, mirror
|
||||||
|
end
|
||||||
|
|
||||||
|
function gr_get_ticks_size(ticks, i)
|
||||||
|
GR.savestate()
|
||||||
|
GR.selntran(0)
|
||||||
|
l = 0.0
|
||||||
|
for (cv, dv) in zip(ticks...)
|
||||||
|
tb = gr_inqtext(0, 0, string(dv))[i]
|
||||||
|
tb_min, tb_max = extrema(tb)
|
||||||
|
l = max(l, tb_max - tb_min)
|
||||||
|
end
|
||||||
|
GR.restorestate()
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
function _update_min_padding!(sp::Subplot{GRBackend})
|
function _update_min_padding!(sp::Subplot{GRBackend})
|
||||||
leftpad = 10mm
|
if !haskey(ENV, "GKSwstype")
|
||||||
toppad = 2mm
|
if isijulia() || (isdefined(Main, :Juno) && Juno.isactive())
|
||||||
rightpad = 2mm
|
ENV["GKSwstype"] = "svg"
|
||||||
bottompad = 6mm
|
end
|
||||||
|
end
|
||||||
|
# Add margin given by the user
|
||||||
|
leftpad = 2mm + sp[:left_margin]
|
||||||
|
toppad = 2mm + sp[:top_margin]
|
||||||
|
rightpad = 4mm + sp[:right_margin]
|
||||||
|
bottompad = 2mm + sp[:bottom_margin]
|
||||||
|
# Add margin for title
|
||||||
if sp[:title] != ""
|
if sp[:title] != ""
|
||||||
toppad += 5mm
|
toppad += 5mm
|
||||||
end
|
end
|
||||||
if sp[:xaxis][:guide] != ""
|
# Add margin for x and y ticks
|
||||||
xticks = axis_drawing_info(sp)[1]
|
xticks, yticks = axis_drawing_info(sp)[1:2]
|
||||||
if !(xticks in (nothing, false))
|
if !(xticks in (nothing, false))
|
||||||
gr_set_font(sp[:xaxis][:tickfont],
|
flip, mirror = gr_set_xticks_font(sp)
|
||||||
halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2],
|
l = gr_get_ticks_size(xticks, 2)
|
||||||
valign = :top,
|
if mirror
|
||||||
color = sp[:xaxis][:foreground_color_axis],
|
toppad += 1mm + gr_plot_size[2] * l * px
|
||||||
rotation = sp[:xaxis][:rotation])
|
|
||||||
h = 0
|
|
||||||
for (cv, dv) in zip(xticks...)
|
|
||||||
tbx, tby = gr_inqtext(0, 0, string(dv))
|
|
||||||
h = max(h, tby[2] - tby[1])
|
|
||||||
end
|
|
||||||
bottompad += 1mm + gr_plot_size[2] * h * px
|
|
||||||
else
|
else
|
||||||
bottompad += 4mm
|
bottompad += 1mm + gr_plot_size[2] * l * px
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if !(yticks in (nothing, false))
|
||||||
|
flip, mirror = gr_set_yticks_font(sp)
|
||||||
|
l = gr_get_ticks_size(yticks, 1)
|
||||||
|
if mirror
|
||||||
|
rightpad += 1mm + gr_plot_size[1] * l * px
|
||||||
|
else
|
||||||
|
leftpad += 1mm + gr_plot_size[1] * l * px
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Add margin for x label
|
||||||
|
if sp[:xaxis][:guide] != ""
|
||||||
|
bottompad += 4mm
|
||||||
|
end
|
||||||
|
# Add margin for y label
|
||||||
if sp[:yaxis][:guide] != ""
|
if sp[:yaxis][:guide] != ""
|
||||||
leftpad += 4mm
|
leftpad += 4mm
|
||||||
end
|
end
|
||||||
sp.minpad = (leftpad, toppad, rightpad, bottompad)
|
sp.minpad = (leftpad, toppad, rightpad, bottompad)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||||
|
_update_min_padding!(sp)
|
||||||
|
|
||||||
# the viewports for this subplot
|
# the viewports for this subplot
|
||||||
viewport_subplot = gr_viewport_from_bbox(sp, bbox(sp), w, h, viewport_canvas)
|
viewport_subplot = gr_viewport_from_bbox(sp, bbox(sp), w, h, viewport_canvas)
|
||||||
viewport_plotarea[:] = gr_viewport_from_bbox(sp, plotarea(sp), w, h, viewport_canvas)
|
viewport_plotarea[:] = gr_viewport_from_bbox(sp, plotarea(sp), w, h, viewport_canvas)
|
||||||
@ -606,7 +663,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
# TODO: can these be generic flags?
|
# TODO: can these be generic flags?
|
||||||
outside_ticks = false
|
outside_ticks = false
|
||||||
cmap = false
|
cmap = false
|
||||||
draw_axes = true
|
draw_axes = sp[:framestyle] != :none
|
||||||
# axes_2d = true
|
# axes_2d = true
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
st = series[:seriestype]
|
st = series[:seriestype]
|
||||||
@ -691,10 +748,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1])
|
ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1])
|
||||||
|
|
||||||
# GR.setlinetype(GR.LINETYPE_DOTTED)
|
# GR.setlinetype(GR.LINETYPE_DOTTED)
|
||||||
if sp[:grid]
|
xaxis[:grid] && GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0)
|
||||||
GR.grid3d(xtick, 0, ztick, xmin, ymax, zmin, 2, 0, 2)
|
yaxis[:grid] && GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0)
|
||||||
GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0)
|
zaxis[:grid] && GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2)
|
||||||
end
|
|
||||||
GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize)
|
GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize)
|
||||||
GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize)
|
GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize)
|
||||||
|
|
||||||
@ -709,34 +765,37 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
GR.setwindow(xmin, xmax, ymin, ymax)
|
GR.setwindow(xmin, xmax, ymin, ymax)
|
||||||
end
|
end
|
||||||
|
|
||||||
xticks, yticks, spine_segs, grid_segs = axis_drawing_info(sp)
|
xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp)
|
||||||
# @show xticks yticks #spine_segs grid_segs
|
# @show xticks yticks #spine_segs grid_segs
|
||||||
|
|
||||||
# draw the grid lines
|
# draw the grid lines
|
||||||
if sp[:grid]
|
if xaxis[:grid]
|
||||||
# gr_set_linecolor(sp[:foreground_color_grid])
|
# gr_set_linecolor(sp[:foreground_color_grid])
|
||||||
# GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
# GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
||||||
gr_set_line(1, :dot, sp[:foreground_color_grid])
|
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
||||||
GR.settransparency(0.5)
|
GR.settransparency(xaxis[:gridalpha])
|
||||||
gr_polyline(coords(grid_segs)...)
|
gr_polyline(coords(xgrid_segs)...)
|
||||||
|
end
|
||||||
|
if yaxis[:grid]
|
||||||
|
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
||||||
|
GR.settransparency(yaxis[:gridalpha])
|
||||||
|
gr_polyline(coords(ygrid_segs)...)
|
||||||
end
|
end
|
||||||
GR.settransparency(1.0)
|
GR.settransparency(1.0)
|
||||||
|
|
||||||
# spine (border) and tick marks
|
# axis lines
|
||||||
gr_set_line(1, :solid, sp[:xaxis][:foreground_color_axis])
|
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
|
||||||
GR.setclip(0)
|
GR.setclip(0)
|
||||||
gr_polyline(coords(spine_segs)...)
|
gr_polyline(coords(xspine_segs)...)
|
||||||
|
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
|
||||||
|
GR.setclip(0)
|
||||||
|
gr_polyline(coords(yspine_segs)...)
|
||||||
GR.setclip(1)
|
GR.setclip(1)
|
||||||
|
|
||||||
if !(xticks in (nothing, false))
|
# tick marks
|
||||||
|
if !(xticks in (:none, nothing, false))
|
||||||
# x labels
|
# x labels
|
||||||
flip = sp[:yaxis][:flip]
|
flip, mirror = gr_set_xticks_font(sp)
|
||||||
mirror = sp[:xaxis][:mirror]
|
|
||||||
gr_set_font(sp[:xaxis][:tickfont],
|
|
||||||
halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2],
|
|
||||||
valign = (mirror ? :bottom : :top),
|
|
||||||
color = sp[:xaxis][:foreground_color_axis],
|
|
||||||
rotation = sp[:xaxis][:rotation])
|
|
||||||
for (cv, dv) in zip(xticks...)
|
for (cv, dv) in zip(xticks...)
|
||||||
# use xor ($) to get the right y coords
|
# use xor ($) to get the right y coords
|
||||||
xi, yi = GR.wctondc(cv, xor(flip, mirror) ? ymax : ymin)
|
xi, yi = GR.wctondc(cv, xor(flip, mirror) ? ymax : ymin)
|
||||||
@ -745,15 +804,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !(yticks in (nothing, false))
|
if !(yticks in (:none, nothing, false))
|
||||||
# y labels
|
# y labels
|
||||||
flip = sp[:xaxis][:flip]
|
flip, mirror = gr_set_yticks_font(sp)
|
||||||
mirror = sp[:yaxis][:mirror]
|
|
||||||
gr_set_font(sp[:yaxis][:tickfont],
|
|
||||||
halign = (mirror ? :left : :right),
|
|
||||||
valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2],
|
|
||||||
color = sp[:yaxis][:foreground_color_axis],
|
|
||||||
rotation = sp[:yaxis][:rotation])
|
|
||||||
for (cv, dv) in zip(yticks...)
|
for (cv, dv) in zip(yticks...)
|
||||||
# use xor ($) to get the right y coords
|
# use xor ($) to get the right y coords
|
||||||
xi, yi = GR.wctondc(xor(flip, mirror) ? xmax : xmin, cv)
|
xi, yi = GR.wctondc(xor(flip, mirror) ? xmax : xmin, cv)
|
||||||
@ -761,6 +814,17 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv))
|
gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# border
|
||||||
|
intensity = sp[:framestyle] == :semi ? 0.5 : 1.0
|
||||||
|
if sp[:framestyle] in (:box, :semi)
|
||||||
|
gr_set_line(intensity, :solid, xaxis[:foreground_color_border])
|
||||||
|
GR.settransparency(intensity)
|
||||||
|
gr_polyline(coords(xborder_segs)...)
|
||||||
|
gr_set_line(intensity, :solid, yaxis[:foreground_color_border])
|
||||||
|
GR.settransparency(intensity)
|
||||||
|
gr_polyline(coords(yborder_segs)...)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
@ -863,7 +927,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if series[:marker_z] != nothing
|
if series[:marker_z] != nothing
|
||||||
zmin, zmax = extrema(series[:marker_z])
|
zmin, zmax = extrema(series[:marker_z])
|
||||||
GR.setspace(zmin, zmax, 0, 90)
|
GR.setspace(zmin, zmax, 0, 90)
|
||||||
GR.setscale(0)
|
|
||||||
end
|
end
|
||||||
gr_draw_markers(series, x, y)
|
gr_draw_markers(series, x, y)
|
||||||
end
|
end
|
||||||
@ -1088,7 +1151,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
st = series[:seriestype]
|
st = series[:seriestype]
|
||||||
gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha])
|
gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha])
|
||||||
|
|
||||||
if st == :shape || series[:fillrange] != nothing
|
if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing
|
||||||
gr_set_fill(series[:fillcolor]) #, series[:fillalpha])
|
gr_set_fill(series[:fillcolor]) #, series[:fillalpha])
|
||||||
l, r = xpos-0.07, xpos-0.01
|
l, r = xpos-0.07, xpos-0.01
|
||||||
b, t = ypos-0.4dy, ypos+0.4dy
|
b, t = ypos-0.4dy, ypos+0.4dy
|
||||||
|
|||||||
@ -18,7 +18,8 @@ Add in functionality to Plots.jl:
|
|||||||
const _inspectdr_attr = merge_with_base_supported([
|
const _inspectdr_attr = merge_with_base_supported([
|
||||||
:annotations,
|
:annotations,
|
||||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||||
:foreground_color_grid, :foreground_color_legend, :foreground_color_title,
|
# :foreground_color_grid,
|
||||||
|
:foreground_color_legend, :foreground_color_title,
|
||||||
:foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text,
|
:foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text,
|
||||||
:label,
|
:label,
|
||||||
:linecolor, :linestyle, :linewidth, :linealpha,
|
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||||
@ -334,15 +335,18 @@ end
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
||||||
const gridon = InspectDR.GridRect(vmajor=true, hmajor=true)
|
|
||||||
const gridoff = InspectDR.GridRect()
|
|
||||||
const plot = sp.o
|
const plot = sp.o
|
||||||
const strip = plot.strips[1] #Only 1 strip supported with Plots.jl
|
const strip = plot.strips[1] #Only 1 strip supported with Plots.jl
|
||||||
|
|
||||||
#No independent control of grid???
|
|
||||||
strip.grid = sp[:grid]? gridon: gridoff
|
|
||||||
|
|
||||||
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
|
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
|
||||||
|
xgrid_show = xaxis[:grid]
|
||||||
|
ygrid_show = yaxis[:grid]
|
||||||
|
|
||||||
|
strip.grid = InspectDR.GridRect(
|
||||||
|
vmajor=xgrid_show, # vminor=xgrid_show,
|
||||||
|
hmajor=ygrid_show, # hminor=ygrid_show,
|
||||||
|
)
|
||||||
|
|
||||||
plot.xscale = _inspectdr_getscale(xaxis[:scale], false)
|
plot.xscale = _inspectdr_getscale(xaxis[:scale], false)
|
||||||
strip.yscale = _inspectdr_getscale(yaxis[:scale], true)
|
strip.yscale = _inspectdr_getscale(yaxis[:scale], true)
|
||||||
xmin, xmax = axis_limits(xaxis)
|
xmin, xmax = axis_limits(xaxis)
|
||||||
|
|||||||
@ -98,7 +98,7 @@ const _pgf_series_extrastyle = KW(
|
|||||||
:xsticks => "xcomb",
|
:xsticks => "xcomb",
|
||||||
)
|
)
|
||||||
|
|
||||||
# PGFPlots uses the anchors to define orientations for example to align left
|
# PGFPlots uses the anchors to define orientations for example to align left
|
||||||
# one needs to use the right edge as anchor
|
# one needs to use the right edge as anchor
|
||||||
const _pgf_annotation_halign = KW(
|
const _pgf_annotation_halign = KW(
|
||||||
:center => "",
|
:center => "",
|
||||||
@ -121,7 +121,7 @@ function pgf_color(grad::ColorGradient)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Generates a colormap for pgfplots based on a ColorGradient
|
# Generates a colormap for pgfplots based on a ColorGradient
|
||||||
function pgf_colormap(grad::ColorGradient)
|
function pgf_colormap(grad::ColorGradient)
|
||||||
join(map(grad.colors) do c
|
join(map(grad.colors) do c
|
||||||
@sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c),blue(c))
|
@sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c),blue(c))
|
||||||
end,", ")
|
end,", ")
|
||||||
@ -266,6 +266,11 @@ function pgf_axis(sp::Subplot, letter)
|
|||||||
push!(style, "$(letter)majorticks=false")
|
push!(style, "$(letter)majorticks=false")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# grid on or off
|
||||||
|
if axis[:grid]
|
||||||
|
push!(style, "$(letter)majorgrids = true")
|
||||||
|
end
|
||||||
|
|
||||||
# limits
|
# limits
|
||||||
# TODO: support zlims
|
# TODO: support zlims
|
||||||
if letter != :z
|
if letter != :z
|
||||||
@ -324,7 +329,6 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
kw[:title] = "$(sp[:title])"
|
kw[:title] = "$(sp[:title])"
|
||||||
end
|
end
|
||||||
|
|
||||||
sp[:grid] && push!(style, "grid = major")
|
|
||||||
if sp[:aspect_ratio] in (1, :equal)
|
if sp[:aspect_ratio] in (1, :equal)
|
||||||
kw[:axisEqual] = "true"
|
kw[:axisEqual] = "true"
|
||||||
end
|
end
|
||||||
@ -360,7 +364,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
kw[:colorbar] = "true"
|
kw[:colorbar] = "true"
|
||||||
end
|
end
|
||||||
# goto is needed to break out of col and series for
|
# goto is needed to break out of col and series for
|
||||||
@goto colorbar_end
|
@goto colorbar_end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -5,7 +5,7 @@ const _plotly_attr = merge_with_base_supported([
|
|||||||
:annotations,
|
:annotations,
|
||||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||||
:foreground_color_legend, :foreground_color_guide,
|
:foreground_color_legend, :foreground_color_guide,
|
||||||
# :foreground_color_grid, :foreground_color_axis,
|
:foreground_color_grid, :foreground_color_axis,
|
||||||
:foreground_color_text, :foreground_color_border,
|
:foreground_color_text, :foreground_color_border,
|
||||||
:foreground_color_title,
|
:foreground_color_title,
|
||||||
:label,
|
:label,
|
||||||
@ -19,7 +19,8 @@ const _plotly_attr = merge_with_base_supported([
|
|||||||
:window_title,
|
:window_title,
|
||||||
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend, :colorbar, :colorbar_title,
|
:grid, :gridalpha, :gridlinewidth,
|
||||||
|
:legend, :colorbar, :colorbar_title,
|
||||||
:marker_z, :fill_z, :levels,
|
:marker_z, :fill_z, :levels,
|
||||||
:ribbon, :quiver,
|
:ribbon, :quiver,
|
||||||
:orientation,
|
:orientation,
|
||||||
@ -213,7 +214,9 @@ function plotly_axis(axis::Axis, sp::Subplot)
|
|||||||
letter = axis[:letter]
|
letter = axis[:letter]
|
||||||
ax = KW(
|
ax = KW(
|
||||||
:title => axis[:guide],
|
:title => axis[:guide],
|
||||||
:showgrid => sp[:grid],
|
:showgrid => axis[:grid],
|
||||||
|
:gridcolor => rgba_string(plot_color(axis[:foreground_color_grid], axis[:gridalpha])),
|
||||||
|
:gridwidth => axis[:gridlinewidth],
|
||||||
:zeroline => false,
|
:zeroline => false,
|
||||||
:ticks => "inside",
|
:ticks => "inside",
|
||||||
)
|
)
|
||||||
@ -229,8 +232,8 @@ function plotly_axis(axis::Axis, sp::Subplot)
|
|||||||
ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide])
|
ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide])
|
||||||
ax[:type] = plotly_scale(axis[:scale])
|
ax[:type] = plotly_scale(axis[:scale])
|
||||||
ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text])
|
ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text])
|
||||||
ax[:tickcolor] = rgba_string(axis[:foreground_color_border])
|
ax[:tickcolor] = rgba_string(axis[:foreground_color_axis])
|
||||||
ax[:linecolor] = rgba_string(axis[:foreground_color_border])
|
ax[:linecolor] = rgba_string(axis[:foreground_color_axis])
|
||||||
|
|
||||||
# lims
|
# lims
|
||||||
lims = axis[:lims]
|
lims = axis[:lims]
|
||||||
@ -435,7 +438,8 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
isscatter = st in (:scatter, :scatter3d, :scattergl)
|
isscatter = st in (:scatter, :scatter3d, :scattergl)
|
||||||
hasmarker = isscatter || series[:markershape] != :none
|
hasmarker = isscatter || series[:markershape] != :none
|
||||||
hasline = st in (:path, :path3d)
|
hasline = st in (:path, :path3d)
|
||||||
hasfillrange = st in (:path, :scatter, :scattergl) && isa(series[:fillrange], AbstractVector)
|
hasfillrange = st in (:path, :scatter, :scattergl) &&
|
||||||
|
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
|
||||||
|
|
||||||
# for surface types, set the data
|
# for surface types, set the data
|
||||||
if st in (:heatmap, :contour, :surface, :wireframe)
|
if st in (:heatmap, :contour, :surface, :wireframe)
|
||||||
@ -459,7 +463,7 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
else
|
else
|
||||||
hasline ? "lines" : "none"
|
hasline ? "lines" : "none"
|
||||||
end
|
end
|
||||||
if series[:fillrange] == true || series[:fillrange] == 0
|
if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple)
|
||||||
d_out[:fill] = "tozeroy"
|
d_out[:fill] = "tozeroy"
|
||||||
d_out[:fillcolor] = rgba_string(series[:fillcolor])
|
d_out[:fillcolor] = rgba_string(series[:fillcolor])
|
||||||
elseif isa(series[:fillrange], AbstractVector)
|
elseif isa(series[:fillrange], AbstractVector)
|
||||||
@ -584,11 +588,21 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
if hasfillrange
|
if hasfillrange
|
||||||
# if hasfillrange is true, return two dictionaries (one for original
|
# if hasfillrange is true, return two dictionaries (one for original
|
||||||
# series, one for series being filled to) instead of one
|
# series, one for series being filled to) instead of one
|
||||||
d_out_fillrange = copy(d_out)
|
d_out_fillrange = deepcopy(d_out)
|
||||||
d_out_fillrange[:y] = series[:fillrange]
|
|
||||||
d_out_fillrange[:showlegend] = false
|
d_out_fillrange[:showlegend] = false
|
||||||
delete!(d_out_fillrange, :fill)
|
if isa(series[:fillrange], AbstractVector)
|
||||||
delete!(d_out_fillrange, :fillcolor)
|
d_out_fillrange[:y] = series[:fillrange]
|
||||||
|
delete!(d_out_fillrange, :fill)
|
||||||
|
delete!(d_out_fillrange, :fillcolor)
|
||||||
|
else
|
||||||
|
# if fillrange is a tuple with upper and lower limit, d_out_fillrange
|
||||||
|
# is the series that will do the filling
|
||||||
|
d_out_fillrange[:x], d_out_fillrange[:y] =
|
||||||
|
concatenate_fillrange(series[:x], series[:fillrange])
|
||||||
|
d_out_fillrange[:line][:width] = 0
|
||||||
|
delete!(d_out, :fill)
|
||||||
|
delete!(d_out, :fillcolor)
|
||||||
|
end
|
||||||
|
|
||||||
return [d_out_fillrange, d_out]
|
return [d_out_fillrange, d_out]
|
||||||
else
|
else
|
||||||
|
|||||||
@ -17,7 +17,8 @@ const _pyplot_attr = merge_with_base_supported([
|
|||||||
:window_title,
|
:window_title,
|
||||||
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend, :legendtitle, :colorbar,
|
:grid, :gridalpha, :gridstyle, :gridlinewidth,
|
||||||
|
:legend, :legendtitle, :colorbar,
|
||||||
:marker_z, :line_z, :fill_z,
|
:marker_z, :line_z, :fill_z,
|
||||||
:levels,
|
:levels,
|
||||||
:ribbon, :quiver, :arrow,
|
:ribbon, :quiver, :arrow,
|
||||||
@ -32,6 +33,7 @@ const _pyplot_attr = merge_with_base_supported([
|
|||||||
:dpi,
|
:dpi,
|
||||||
:colorbar_title,
|
:colorbar_title,
|
||||||
:stride,
|
:stride,
|
||||||
|
:framestyle,
|
||||||
])
|
])
|
||||||
const _pyplot_seriestype = [
|
const _pyplot_seriestype = [
|
||||||
:path, :steppre, :steppost, :shape,
|
:path, :steppre, :steppost, :shape,
|
||||||
@ -1053,7 +1055,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
end
|
end
|
||||||
py_set_scale(ax, axis)
|
py_set_scale(ax, axis)
|
||||||
py_set_lims(ax, axis)
|
py_set_lims(ax, axis)
|
||||||
py_set_ticks(ax, get_ticks(axis), letter)
|
ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis)
|
||||||
|
py_set_ticks(ax, ticks, letter)
|
||||||
ax[Symbol("set_", letter, "label")](axis[:guide])
|
ax[Symbol("set_", letter, "label")](axis[:guide])
|
||||||
if get(axis.d, :flip, false)
|
if get(axis.d, :flip, false)
|
||||||
ax[Symbol("invert_", letter, "axis")]()
|
ax[Symbol("invert_", letter, "axis")]()
|
||||||
@ -1065,9 +1068,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
lab[:set_family](axis[:tickfont].family)
|
lab[:set_family](axis[:tickfont].family)
|
||||||
lab[:set_rotation](axis[:rotation])
|
lab[:set_rotation](axis[:rotation])
|
||||||
end
|
end
|
||||||
if sp[:grid]
|
if axis[:grid] && !(ticks in (:none, nothing, false))
|
||||||
fgcolor = py_color(sp[:foreground_color_grid])
|
fgcolor = py_color(axis[:foreground_color_grid])
|
||||||
pyaxis[:grid](true, color = fgcolor, linestyle = ":")
|
pyaxis[:grid](true,
|
||||||
|
color = fgcolor,
|
||||||
|
linestyle = py_linestyle(:line, axis[:gridstyle]),
|
||||||
|
linewidth = axis[:gridlinewidth],
|
||||||
|
alpha = axis[:gridalpha])
|
||||||
ax[:set_axisbelow](true)
|
ax[:set_axisbelow](true)
|
||||||
end
|
end
|
||||||
py_set_axis_colors(ax, axis)
|
py_set_axis_colors(ax, axis)
|
||||||
@ -1084,6 +1091,24 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
|
|
||||||
# this sets the bg color inside the grid
|
# this sets the bg color inside the grid
|
||||||
ax[set_facecolor_sym](py_color(sp[:background_color_inside]))
|
ax[set_facecolor_sym](py_color(sp[:background_color_inside]))
|
||||||
|
|
||||||
|
# framestyle
|
||||||
|
if !ispolar(sp) && !is3d(sp)
|
||||||
|
if sp[:framestyle] == :semi
|
||||||
|
intensity = 0.5
|
||||||
|
ax[:spines]["right"][:set_alpha](intensity)
|
||||||
|
ax[:spines]["top"][:set_alpha](intensity)
|
||||||
|
ax[:spines]["right"][:set_linewidth](intensity)
|
||||||
|
ax[:spines]["top"][:set_linewidth](intensity)
|
||||||
|
elseif sp[:framestyle] == :axes
|
||||||
|
ax[:spines]["right"][:set_visible](false)
|
||||||
|
ax[:spines]["top"][:set_visible](false)
|
||||||
|
elseif sp[:framestyle] in (:grid, :none)
|
||||||
|
for (loc, spine) in ax[:spines]
|
||||||
|
spine[:set_visible](false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
py_drawfig(fig)
|
py_drawfig(fig)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -22,6 +22,13 @@ immutable Shape
|
|||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
Shape(x, y)
|
||||||
|
Shape(vertices)
|
||||||
|
|
||||||
|
Construct a polygon to be plotted
|
||||||
|
"""
|
||||||
Shape(verts::AVec) = Shape(unzip(verts)...)
|
Shape(verts::AVec) = Shape(unzip(verts)...)
|
||||||
Shape(s::Shape) = deepcopy(s)
|
Shape(s::Shape) = deepcopy(s)
|
||||||
|
|
||||||
@ -32,6 +39,7 @@ vertices(shape::Shape) = collect(zip(shape.x, shape.y))
|
|||||||
#deprecated
|
#deprecated
|
||||||
@deprecate shape_coords coords
|
@deprecate shape_coords coords
|
||||||
|
|
||||||
|
"return the vertex points from a Shape or Segments object"
|
||||||
function coords(shape::Shape)
|
function coords(shape::Shape)
|
||||||
shape.x, shape.y
|
shape.x, shape.y
|
||||||
end
|
end
|
||||||
@ -156,6 +164,7 @@ Shape(k::Symbol) = deepcopy(_shapes[k])
|
|||||||
|
|
||||||
|
|
||||||
# uses the centroid calculation from https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
|
# uses the centroid calculation from https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
|
||||||
|
"return the centroid of a Shape"
|
||||||
function center(shape::Shape)
|
function center(shape::Shape)
|
||||||
x, y = coords(shape)
|
x, y = coords(shape)
|
||||||
n = length(x)
|
n = length(x)
|
||||||
@ -189,6 +198,7 @@ function scale(shape::Shape, x::Real, y::Real = x, c = center(shape))
|
|||||||
scale!(shapecopy, x, y, c)
|
scale!(shapecopy, x, y, c)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"translate a Shape in space"
|
||||||
function translate!(shape::Shape, x::Real, y::Real = x)
|
function translate!(shape::Shape, x::Real, y::Real = x)
|
||||||
sx, sy = coords(shape)
|
sx, sy = coords(shape)
|
||||||
for i=1:length(sx)
|
for i=1:length(sx)
|
||||||
@ -227,6 +237,7 @@ function rotate!(shape::Shape, Θ::Real, c = center(shape))
|
|||||||
shape
|
shape
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"rotate an object in space"
|
||||||
function rotate(shape::Shape, Θ::Real, c = center(shape))
|
function rotate(shape::Shape, Θ::Real, c = center(shape))
|
||||||
shapecopy = deepcopy(shape)
|
shapecopy = deepcopy(shape)
|
||||||
rotate!(shapecopy, Θ, c)
|
rotate!(shapecopy, Θ, c)
|
||||||
@ -331,6 +342,11 @@ immutable PlotText
|
|||||||
end
|
end
|
||||||
PlotText(str) = PlotText(string(str), font())
|
PlotText(str) = PlotText(string(str), font())
|
||||||
|
|
||||||
|
"""
|
||||||
|
text(string, args...)
|
||||||
|
|
||||||
|
Create a PlotText object wrapping a string with font info, for plot annotations
|
||||||
|
"""
|
||||||
text(t::PlotText) = t
|
text(t::PlotText) = t
|
||||||
text(str::AbstractString, f::Font) = PlotText(str, f)
|
text(str::AbstractString, f::Font) = PlotText(str, f)
|
||||||
function text(str, args...)
|
function text(str, args...)
|
||||||
@ -350,6 +366,11 @@ immutable Stroke
|
|||||||
style
|
style
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
stroke(args...; alpha = nothing)
|
||||||
|
|
||||||
|
Define the properties of the stroke used in plotting lines
|
||||||
|
"""
|
||||||
function stroke(args...; alpha = nothing)
|
function stroke(args...; alpha = nothing)
|
||||||
width = 1
|
width = 1
|
||||||
color = :black
|
color = :black
|
||||||
@ -597,6 +618,12 @@ immutable Arrow
|
|||||||
headwidth::Float64
|
headwidth::Float64
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
arrow(args...)
|
||||||
|
|
||||||
|
Define arrowheads to apply to lines - args are `style` (`:open` or `:closed`),
|
||||||
|
`side` (`:head`, `:tail` or `:both`), `headlength` and `headwidth`
|
||||||
|
"""
|
||||||
function arrow(args...)
|
function arrow(args...)
|
||||||
style = :simple
|
style = :simple
|
||||||
side = :head
|
side = :head
|
||||||
@ -652,7 +679,7 @@ immutable Formatted{T}
|
|||||||
end
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
"create a BezierCurve for plotting"
|
||||||
type BezierCurve{T <: FixedSizeArrays.Vec}
|
type BezierCurve{T <: FixedSizeArrays.Vec}
|
||||||
control_points::Vector{T}
|
control_points::Vector{T}
|
||||||
end
|
end
|
||||||
|
|||||||
@ -155,7 +155,7 @@ PlotExample("Subplots",
|
|||||||
""",
|
""",
|
||||||
[:(begin
|
[:(begin
|
||||||
l = @layout([a{0.1h}; b [c;d e]])
|
l = @layout([a{0.1h}; b [c;d e]])
|
||||||
plot(randn(100,5), layout=l, t=[:line :histogram :scatter :steppre :bar], leg=false, ticks=nothing, border=false)
|
plot(randn(100,5), layout=l, t=[:line :histogram :scatter :steppre :bar], leg=false, ticks=nothing, border=:none)
|
||||||
end)]
|
end)]
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ PlotExample("Layouts, margins, label rotation, title location",
|
|||||||
[:(begin
|
[:(begin
|
||||||
plot(rand(100,6),layout=@layout([a b; c]),title=["A" "B" "C"],
|
plot(rand(100,6),layout=@layout([a b; c]),title=["A" "B" "C"],
|
||||||
title_location=:left, left_margin=[20mm 0mm],
|
title_location=:left, left_margin=[20mm 0mm],
|
||||||
bottom_margin=50px, xrotation=60)
|
bottom_margin=10px, xrotation=60)
|
||||||
end)]
|
end)]
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ PlotExample("Animation with subplots",
|
|||||||
),
|
),
|
||||||
|
|
||||||
PlotExample("Spy",
|
PlotExample("Spy",
|
||||||
"For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`",
|
"For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`.",
|
||||||
[:(begin
|
[:(begin
|
||||||
a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10))
|
a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10))
|
||||||
b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10))
|
b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10))
|
||||||
@ -329,6 +329,26 @@ PlotExample("Spy",
|
|||||||
end)]
|
end)]
|
||||||
),
|
),
|
||||||
|
|
||||||
|
PlotExample("Magic grid argument",
|
||||||
|
"The grid lines can be modified individually for each axis with the magic `grid` argument.",
|
||||||
|
[:(begin
|
||||||
|
x = rand(10)
|
||||||
|
p1 = plot(x, title = "Default looks")
|
||||||
|
p2 = plot(x, grid = (:y, :olivedrab, :dot, 1, 0.9), title = "Modified y grid")
|
||||||
|
p3 = plot(deepcopy(p2), title = "Add x grid")
|
||||||
|
xgrid!(p3, :on, :cadetblue, 2, :dashdot, 0.4)
|
||||||
|
plot(p1, p2, p3, layout = (1, 3), label = "", fillrange = 0, fillalpha = 0.3)
|
||||||
|
end)]
|
||||||
|
),
|
||||||
|
|
||||||
|
PlotExample("Framestyle",
|
||||||
|
"The style of the frame/axes of a (sub)plot can be changed with the `framestyle` attribute. The default framestyle is `:axes`.",
|
||||||
|
[:(begin
|
||||||
|
histogram(fill(randn(1000), 5), framestyle = [:box :semi :axes :grid :none],
|
||||||
|
title = [":box" ":semi" ":axes" ":grid" ":none"], color = RowVector(1:5), layout = 5, label = "")
|
||||||
|
end)]
|
||||||
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------
|
||||||
@ -348,6 +368,13 @@ function test_examples(pkgname::Symbol, idx::Int; debug = false, disp = true)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# generate all plots and create a dict mapping idx --> plt
|
# generate all plots and create a dict mapping idx --> plt
|
||||||
|
"""
|
||||||
|
test_examples(pkgname[, idx]; debug = false, disp = true, sleep = nothing,
|
||||||
|
skip = [], only = nothing
|
||||||
|
|
||||||
|
Run the `idx` test example for a given backend, or all examples if `idx`
|
||||||
|
is not specified.
|
||||||
|
"""
|
||||||
function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = nothing,
|
function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = nothing,
|
||||||
skip = [], only = nothing)
|
skip = [], only = nothing)
|
||||||
Plots._debugMode.on = debug
|
Plots._debugMode.on = debug
|
||||||
|
|||||||
@ -133,7 +133,12 @@ make_measure_hor(m::Measure) = m
|
|||||||
make_measure_vert(n::Number) = n * h
|
make_measure_vert(n::Number) = n * h
|
||||||
make_measure_vert(m::Measure) = m
|
make_measure_vert(m::Measure) = m
|
||||||
|
|
||||||
|
"""
|
||||||
|
bbox(x, y, w, h [,originargs...])
|
||||||
|
bbox(layout)
|
||||||
|
|
||||||
|
Create a bounding box for plotting
|
||||||
|
"""
|
||||||
function bbox(x, y, w, h, oarg1::Symbol, originargs::Symbol...)
|
function bbox(x, y, w, h, oarg1::Symbol, originargs::Symbol...)
|
||||||
oargs = vcat(oarg1, originargs...)
|
oargs = vcat(oarg1, originargs...)
|
||||||
orighor = :left
|
orighor = :left
|
||||||
@ -253,6 +258,13 @@ type GridLayout <: AbstractLayout
|
|||||||
attr::KW
|
attr::KW
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
grid(args...; kw...)
|
||||||
|
|
||||||
|
Create a grid layout for subplots. `args` specify the dimensions, e.g.
|
||||||
|
`grid(3,2, widths = (0.6,04))` creates a grid with three rows and two
|
||||||
|
columns of different width.
|
||||||
|
"""
|
||||||
grid(args...; kw...) = GridLayout(args...; kw...)
|
grid(args...; kw...) = GridLayout(args...; kw...)
|
||||||
|
|
||||||
function GridLayout(dims...;
|
function GridLayout(dims...;
|
||||||
|
|||||||
@ -97,6 +97,13 @@ function addExtension(fn::AbstractString, ext::AbstractString)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
savefig([plot,] filename)
|
||||||
|
|
||||||
|
Save a Plot (the current plot if `plot` is not passed) to file. The file
|
||||||
|
type is inferred from the file extension. All backends support png and pdf
|
||||||
|
file types, some also support svg, ps, eps, html and tex.
|
||||||
|
"""
|
||||||
function savefig(plt::Plot, fn::AbstractString)
|
function savefig(plt::Plot, fn::AbstractString)
|
||||||
|
|
||||||
# get the extension
|
# get the extension
|
||||||
@ -119,7 +126,11 @@ savefig(fn::AbstractString) = savefig(current(), fn)
|
|||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
"""
|
||||||
|
gui([plot])
|
||||||
|
|
||||||
|
Display a plot using the backends' gui window
|
||||||
|
"""
|
||||||
gui(plt::Plot = current()) = display(PlotsDisplay(), plt)
|
gui(plt::Plot = current()) = display(PlotsDisplay(), plt)
|
||||||
|
|
||||||
# IJulia only... inline display
|
# IJulia only... inline display
|
||||||
@ -198,6 +209,7 @@ for mime in keys(_mimeformats)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"Close all open gui windows of the current backend"
|
||||||
closeall() = closeall(backend())
|
closeall() = closeall(backend())
|
||||||
|
|
||||||
|
|
||||||
@ -266,6 +278,7 @@ using Requires
|
|||||||
show(io, MIME("text/html"), plt)
|
show(io, MIME("text/html"), plt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ENV["MPLBACKEND"] = "Agg"
|
||||||
set_ijulia_output("text/html")
|
set_ijulia_output("text/html")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -60,29 +60,26 @@ function _process_userrecipes(plt::Plot, d::KW, args)
|
|||||||
args = _preprocess_args(d, args, still_to_process)
|
args = _preprocess_args(d, args, still_to_process)
|
||||||
|
|
||||||
# for plotting recipes, swap out the args and update the parameter dictionary
|
# for plotting recipes, swap out the args and update the parameter dictionary
|
||||||
# we are keeping a queue of series that still need to be processed.
|
# we are keeping a stack of series that still need to be processed.
|
||||||
# each pass through the loop, we pop one off and apply the recipe.
|
# each pass through the loop, we pop one off and apply the recipe.
|
||||||
# the recipe will return a list a Series objects... the ones that are
|
# the recipe will return a list a Series objects... the ones that are
|
||||||
# finished (no more args) get added to the kw_list, and the rest go into the queue
|
# finished (no more args) get added to the kw_list, the ones that are not
|
||||||
# for processing.
|
# are placed on top of the stack and are then processed further.
|
||||||
kw_list = KW[]
|
kw_list = KW[]
|
||||||
while !isempty(still_to_process)
|
while !isempty(still_to_process)
|
||||||
# grab the first in line to be processed and pass it through apply_recipe
|
# grab the first in line to be processed and either add it to the kw_list or
|
||||||
# to generate a list of RecipeData objects (data + attributes)
|
# pass it through apply_recipe to generate a list of RecipeData objects (data + attributes)
|
||||||
|
# for further processing.
|
||||||
next_series = shift!(still_to_process)
|
next_series = shift!(still_to_process)
|
||||||
rd_list = RecipesBase.apply_recipe(next_series.d, next_series.args...)
|
# recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes
|
||||||
for recipedata in rd_list
|
if !(typeof(next_series) <: RecipeData)
|
||||||
# recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes
|
error("Inputs couldn't be processed... expected RecipeData but got: $next_series")
|
||||||
if !(typeof(recipedata) <: RecipeData)
|
end
|
||||||
error("Inputs couldn't be processed... expected RecipeData but got: $recipedata")
|
if isempty(next_series.args)
|
||||||
end
|
_process_userrecipe(plt, kw_list, next_series)
|
||||||
|
else
|
||||||
if isempty(recipedata.args)
|
rd_list = RecipesBase.apply_recipe(next_series.d, next_series.args...)
|
||||||
_process_userrecipe(plt, kw_list, recipedata)
|
prepend!(still_to_process,rd_list)
|
||||||
else
|
|
||||||
# args are non-empty, so there's still processing to do... add it back to the queue
|
|
||||||
push!(still_to_process, recipedata)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -213,7 +210,7 @@ function _plot_setup(plt::Plot, d::KW, kw_list::Vector{KW})
|
|||||||
# TODO: init subplots here
|
# TODO: init subplots here
|
||||||
_update_plot_args(plt, d)
|
_update_plot_args(plt, d)
|
||||||
if !plt.init
|
if !plt.init
|
||||||
plt.o = _create_backend_figure(plt)
|
plt.o = Base.invokelatest(_create_backend_figure, plt)
|
||||||
|
|
||||||
# create the layout and subplots from the inputs
|
# create the layout and subplots from the inputs
|
||||||
plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr)
|
plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr)
|
||||||
|
|||||||
@ -6,6 +6,10 @@ const CURRENT_PLOT = CurrentPlot(Nullable{AbstractPlot}())
|
|||||||
|
|
||||||
isplotnull() = isnull(CURRENT_PLOT.nullableplot)
|
isplotnull() = isnull(CURRENT_PLOT.nullableplot)
|
||||||
|
|
||||||
|
"""
|
||||||
|
current()
|
||||||
|
Returns the Plot object for the current plot
|
||||||
|
"""
|
||||||
function current()
|
function current()
|
||||||
if isplotnull()
|
if isplotnull()
|
||||||
error("No current plot/subplot")
|
error("No current plot/subplot")
|
||||||
|
|||||||
@ -14,6 +14,12 @@ function lookup_aliases(attrtype, attribute)
|
|||||||
error("There is no attribute named $attribute in $attrtype")
|
error("There is no attribute named $attribute in $attrtype")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
plotattr([attr])
|
||||||
|
|
||||||
|
Look up the properties of a Plots attribute, or specify an attribute type. Call `plotattr()` for options.
|
||||||
|
The information is the same as that given on https://juliaplots.github.io/attributes/.
|
||||||
|
"""
|
||||||
function plotattr()
|
function plotattr()
|
||||||
println("Specify an attribute type to get a list of supported attributes. Options are $(attrtypes())")
|
println("Specify an attribute type to get a list of supported attributes. Options are $(attrtypes())")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -510,8 +510,10 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode
|
|||||||
v = vs[dim]
|
v = vs[dim]
|
||||||
|
|
||||||
if mode == :auto
|
if mode == :auto
|
||||||
30
|
mode = :fd
|
||||||
elseif mode == :sqrt # Square-root choice
|
end
|
||||||
|
|
||||||
|
if mode == :sqrt # Square-root choice
|
||||||
_cl(sqrt(n))
|
_cl(sqrt(n))
|
||||||
elseif mode == :sturges # Sturges' formula
|
elseif mode == :sturges # Sturges' formula
|
||||||
_cl(log2(n)) + 1
|
_cl(log2(n)) + 1
|
||||||
@ -550,7 +552,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
@recipe function f(::Type{Val{:histogram}}, x, y, z)
|
@recipe function f(::Type{Val{:histogram}}, x, y, z)
|
||||||
seriestype := :barhist
|
seriestype := length(y) > 1e6 ? :stephist : :barhist
|
||||||
()
|
()
|
||||||
end
|
end
|
||||||
@deps histogram barhist
|
@deps histogram barhist
|
||||||
@ -847,6 +849,7 @@ end
|
|||||||
|
|
||||||
# TODO: move OHLC to PlotRecipes finance.jl
|
# TODO: move OHLC to PlotRecipes finance.jl
|
||||||
|
|
||||||
|
"Represent Open High Low Close data (used in finance)"
|
||||||
type OHLC{T<:Real}
|
type OHLC{T<:Real}
|
||||||
open::T
|
open::T
|
||||||
high::T
|
high::T
|
||||||
|
|||||||
@ -509,12 +509,25 @@ end
|
|||||||
# nothing
|
# nothing
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
splittable_kw(key, val, lengthGroup) = false
|
||||||
|
splittable_kw(key, val::AbstractArray, lengthGroup) = (key != :group) && size(val,1) == lengthGroup
|
||||||
|
splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup))
|
||||||
|
|
||||||
|
split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...]
|
||||||
|
split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val)
|
||||||
|
|
||||||
# split the group into 1 series per group, and set the label and idxfilter for each
|
# split the group into 1 series per group, and set the label and idxfilter for each
|
||||||
@recipe function f(groupby::GroupBy, args...)
|
@recipe function f(groupby::GroupBy, args...)
|
||||||
|
lengthGroup = maximum(union(groupby.groupIds...))
|
||||||
for (i,glab) in enumerate(groupby.groupLabels)
|
for (i,glab) in enumerate(groupby.groupLabels)
|
||||||
@series begin
|
@series begin
|
||||||
label --> string(glab)
|
label --> string(glab)
|
||||||
idxfilter --> groupby.groupIds[i]
|
idxfilter --> groupby.groupIds[i]
|
||||||
|
for (key,val) in d
|
||||||
|
if splittable_kw(key, val, lengthGroup)
|
||||||
|
:($key) := split_kw(key, val, groupby.groupIds[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
args
|
args
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,6 +13,11 @@ function Subplot{T<:AbstractBackend}(::T; parent = RootLayout())
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
plotarea(subplot)
|
||||||
|
|
||||||
|
Return the bounding box of a subplot
|
||||||
|
"""
|
||||||
plotarea(sp::Subplot) = sp.plotarea
|
plotarea(sp::Subplot) = sp.plotarea
|
||||||
plotarea!(sp::Subplot, bbox::BoundingBox) = (sp.plotarea = bbox)
|
plotarea!(sp::Subplot, bbox::BoundingBox) = (sp.plotarea = bbox)
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
|
"""
|
||||||
|
theme(s::Symbol)
|
||||||
|
|
||||||
|
Specify the colour theme for plots.
|
||||||
|
"""
|
||||||
function theme(s::Symbol; kw...)
|
function theme(s::Symbol; kw...)
|
||||||
# reset?
|
# reset?
|
||||||
if s == :none || s == :default
|
if s == :none || s == :default
|
||||||
|
|||||||
33
src/utils.jl
33
src/utils.jl
@ -137,7 +137,7 @@ function imageHack(d::KW)
|
|||||||
end
|
end
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
|
|
||||||
|
"Build line segments for plotting"
|
||||||
type Segments{T}
|
type Segments{T}
|
||||||
pts::Vector{T}
|
pts::Vector{T}
|
||||||
end
|
end
|
||||||
@ -185,6 +185,7 @@ type SegmentsIterator
|
|||||||
args::Tuple
|
args::Tuple
|
||||||
n::Int
|
n::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
function iter_segments(args...)
|
function iter_segments(args...)
|
||||||
tup = Plots.wraptuple(args)
|
tup = Plots.wraptuple(args)
|
||||||
n = maximum(map(length, tup))
|
n = maximum(map(length, tup))
|
||||||
@ -495,14 +496,42 @@ function make_fillrange_from_ribbon(kw::KW)
|
|||||||
rib1, rib2 = -first(rib), last(rib)
|
rib1, rib2 = -first(rib), last(rib)
|
||||||
# kw[:ribbon] = nothing
|
# kw[:ribbon] = nothing
|
||||||
kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2)
|
kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2)
|
||||||
|
(get(kw, :fillalpha, nothing) == nothing) && (kw[:fillalpha] = 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
#turn tuple of fillranges to one path
|
||||||
|
function concatenate_fillrange(x,y::Tuple)
|
||||||
|
rib1, rib2 = first(y), last(y)
|
||||||
|
yline = vcat(rib1,(rib2)[end:-1:1])
|
||||||
|
xline = vcat(x,x[end:-1:1])
|
||||||
|
return xline, yline
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_sp_lims(sp::Subplot, letter::Symbol)
|
function get_sp_lims(sp::Subplot, letter::Symbol)
|
||||||
axis_limits(sp[Symbol(letter, :axis)])
|
axis_limits(sp[Symbol(letter, :axis)])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
xlims([plt])
|
||||||
|
|
||||||
|
Returns the x axis limits of the current plot or subplot
|
||||||
|
"""
|
||||||
xlims(sp::Subplot) = get_sp_lims(sp, :x)
|
xlims(sp::Subplot) = get_sp_lims(sp, :x)
|
||||||
|
|
||||||
|
"""
|
||||||
|
ylims([plt])
|
||||||
|
|
||||||
|
Returns the y axis limits of the current plot or subplot
|
||||||
|
"""
|
||||||
ylims(sp::Subplot) = get_sp_lims(sp, :y)
|
ylims(sp::Subplot) = get_sp_lims(sp, :y)
|
||||||
|
|
||||||
|
"""
|
||||||
|
zlims([plt])
|
||||||
|
|
||||||
|
Returns the z axis limits of the current plot or subplot
|
||||||
|
"""
|
||||||
zlims(sp::Subplot) = get_sp_lims(sp, :z)
|
zlims(sp::Subplot) = get_sp_lims(sp, :z)
|
||||||
|
|
||||||
xlims(plt::Plot, sp_idx::Int = 1) = xlims(plt[sp_idx])
|
xlims(plt::Plot, sp_idx::Int = 1) = xlims(plt[sp_idx])
|
||||||
ylims(plt::Plot, sp_idx::Int = 1) = ylims(plt[sp_idx])
|
ylims(plt::Plot, sp_idx::Int = 1) = ylims(plt[sp_idx])
|
||||||
zlims(plt::Plot, sp_idx::Int = 1) = zlims(plt[sp_idx])
|
zlims(plt::Plot, sp_idx::Int = 1) = zlims(plt[sp_idx])
|
||||||
@ -536,7 +565,7 @@ allFunctions(arg) = trueOrAllTrue(a -> isa(a, Function), arg)
|
|||||||
"""
|
"""
|
||||||
Allows temporary setting of backend and defaults for Plots. Settings apply only for the `do` block. Example:
|
Allows temporary setting of backend and defaults for Plots. Settings apply only for the `do` block. Example:
|
||||||
```
|
```
|
||||||
with(:gadfly, size=(400,400), type=:histogram) do
|
with(:gr, size=(400,400), type=:histogram) do
|
||||||
plot(rand(10))
|
plot(rand(10))
|
||||||
plot(rand(10))
|
plot(rand(10))
|
||||||
end
|
end
|
||||||
|
|||||||
@ -23,7 +23,7 @@ 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
|
# 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)
|
# is referenced in a button press callback (the button clicked callback will call notify() on that condition)
|
||||||
|
|
||||||
const _current_plots_version = v"0.12.1"
|
const _current_plots_version = v"0.12.3"
|
||||||
|
|
||||||
|
|
||||||
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
|
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
|
||||||
@ -42,7 +42,8 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is
|
|||||||
fn = "ref$idx.png"
|
fn = "ref$idx.png"
|
||||||
|
|
||||||
# firgure out version info
|
# firgure out version info
|
||||||
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
|
vns = filter(x->x[1] != '.', readdir(refdir))
|
||||||
|
versions = sort(VersionNumber.(vns), rev = true)
|
||||||
versions = filter(v -> v <= _current_plots_version, versions)
|
versions = filter(v -> v <= _current_plots_version, versions)
|
||||||
# @show refdir fn versions
|
# @show refdir fn versions
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ default(show=false, reuse=true)
|
|||||||
img_eps = isinteractive() ? 1e-2 : 10e-2
|
img_eps = isinteractive() ? 1e-2 : 10e-2
|
||||||
|
|
||||||
@testset "GR" begin
|
@testset "GR" begin
|
||||||
|
ENV["GKSwstype"] = "100"
|
||||||
@test gr() == Plots.GRBackend()
|
@test gr() == Plots.GRBackend()
|
||||||
@test backend() == Plots.GRBackend()
|
@test backend() == Plots.GRBackend()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user