improve coverage (#4155)
This commit is contained in:
parent
d3817796a4
commit
02d08beb1e
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
env:
|
||||
GKS_ENCODING: "utf8"
|
||||
GKSwstype: "100"
|
||||
GKSwstype: "nul"
|
||||
|
||||
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
@ -55,19 +55,16 @@ jobs:
|
||||
${{ runner.os }}-test-
|
||||
${{ runner.os }}-
|
||||
|
||||
## maybe required if we ever want to run graphical tests for plotly
|
||||
# OS Dependencies
|
||||
# - name: Ubuntu OS dependencies
|
||||
# if: startsWith(matrix.os,'ubuntu')
|
||||
# run: |
|
||||
# ./test/install_wkhtmltoimage.sh
|
||||
|
||||
# TESTCMD
|
||||
- name: Default TESTCMD
|
||||
run: echo "TESTCMD=julia" >> $GITHUB_ENV
|
||||
- name: Ubuntu TESTCMD
|
||||
if: startsWith(matrix.os,'ubuntu')
|
||||
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
|
||||
run: |
|
||||
echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install gnuplot poppler-utils texlive-{latex-base,latex-extra,luatex}
|
||||
sudo fc-cache -vr
|
||||
|
||||
# Julia Dependencies
|
||||
- name: Install Julia dependencies
|
||||
@ -82,7 +79,9 @@ jobs:
|
||||
|
||||
# Codecov
|
||||
- uses: julia-actions/julia-processcoverage@v1
|
||||
if: startsWith(matrix.os,'ubuntu')
|
||||
- uses: codecov/codecov-action@v2
|
||||
if: startsWith(matrix.os,'ubuntu')
|
||||
with:
|
||||
file: lcov.info
|
||||
|
||||
|
||||
@ -68,10 +68,12 @@ julia = "1.6"
|
||||
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
|
||||
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
||||
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
|
||||
Gaston = "4b11ee91-296f-5714-9832-002c20994614"
|
||||
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
|
||||
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
|
||||
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
|
||||
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
|
||||
InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d"
|
||||
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||||
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
|
||||
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
|
||||
@ -88,4 +90,4 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
|
||||
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
|
||||
|
||||
[targets]
|
||||
test = ["Colors", "Distributions", "FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "PlotlyBase", "PyPlot", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
|
||||
test = ["Colors", "Distributions", "FileIO", "Gaston", "Gtk", "ImageMagick", "Images", "InspectDR", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "PlotlyBase", "PyPlot", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
# significant contributions by: @pkofod
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
|
||||
# COV_EXCL_START
|
||||
const _pgfplots_linestyles = KW(
|
||||
:solid => "solid",
|
||||
:dash => "dashed",
|
||||
@ -740,3 +740,5 @@ function _display(plt::Plot{PGFPlotsBackend})
|
||||
# cleanup
|
||||
PGFPlots.cleanup(plt.o)
|
||||
end
|
||||
|
||||
# COV_EXCL_STOP
|
||||
|
||||
@ -269,27 +269,25 @@ function png(plt::Plot{UnicodePlotsBackend}, fn::AbstractString)
|
||||
else
|
||||
img = UnicodePlots.png_image(plt.o[sps += 1])
|
||||
canvas_type = eltype(img)
|
||||
sz = size(img)
|
||||
s1[r, c] = sz[1]
|
||||
s2[r, c] = sz[2]
|
||||
h, w = size(img)
|
||||
s1[r, c] = h
|
||||
s2[r, c] = w
|
||||
push!(imgs, img)
|
||||
end
|
||||
end
|
||||
end
|
||||
if canvas_type !== nothing
|
||||
rows = maximum(sum(s1; dims = 1))
|
||||
cols = maximum(sum(s2; dims = 2))
|
||||
img = zeros(canvas_type, rows, cols)
|
||||
m1 = maximum(s1; dims = 2)
|
||||
m2 = maximum(s2; dims = 1)
|
||||
img = zeros(canvas_type, sum(m1), sum(m2))
|
||||
sps = 0
|
||||
n1 = 1
|
||||
for r in 1:nr
|
||||
n2 = 1
|
||||
for c in 1:nc
|
||||
sp = imgs[sps += 1]
|
||||
sz = size(sp)
|
||||
img[n1:(n1 + (sz[1] - 1)), n2:(n2 + (sz[2] - 1))] = sp
|
||||
h, w = size(sp)
|
||||
img[n1:(n1 + (h - 1)), n2:(n2 + (w - 1))] = sp
|
||||
n2 += m2[c]
|
||||
end
|
||||
n1 += m1[r]
|
||||
|
||||
@ -174,20 +174,19 @@ end
|
||||
|
||||
translate(shape::Shape, x::Real, y::Real = x) = translate!(deepcopy(shape), x, y)
|
||||
|
||||
rotate_x(x::Real, y::Real, Θ::Real, centerx::Real, centery::Real) =
|
||||
((x - centerx) * cos(Θ) - (y - centery) * sin(Θ) + centerx)
|
||||
rotate_x(x::Real, y::Real, θ::Real, centerx::Real, centery::Real) =
|
||||
((x - centerx) * cos(θ) - (y - centery) * sin(θ) + centerx)
|
||||
|
||||
rotate_y(x::Real, y::Real, Θ::Real, centerx::Real, centery::Real) =
|
||||
((y - centery) * cos(Θ) + (x - centerx) * sin(Θ) + centery)
|
||||
rotate_y(x::Real, y::Real, θ::Real, centerx::Real, centery::Real) =
|
||||
((y - centery) * cos(θ) + (x - centerx) * sin(θ) + centery)
|
||||
|
||||
rotate(x::Real, y::Real, θ::Real, c = center(shape)) =
|
||||
(rotate_x(x, y, Θ, c...), rotate_y(x, y, Θ, c...))
|
||||
rotate(x::Real, y::Real, θ::Real, c) = (rotate_x(x, y, θ, c...), rotate_y(x, y, θ, c...))
|
||||
|
||||
function rotate!(shape::Shape, Θ::Real, c = center(shape))
|
||||
function rotate!(shape::Shape, θ::Real, c = center(shape))
|
||||
x, y = coords(shape)
|
||||
for i in eachindex(x)
|
||||
xi = rotate_x(x[i], y[i], Θ, c...)
|
||||
yi = rotate_y(x[i], y[i], Θ, c...)
|
||||
xi = rotate_x(x[i], y[i], θ, c...)
|
||||
yi = rotate_y(x[i], y[i], θ, c...)
|
||||
x[i], y[i] = xi, yi
|
||||
end
|
||||
shape
|
||||
|
||||
@ -169,7 +169,7 @@ const _examples = PlotExample[
|
||||
)],
|
||||
),
|
||||
PlotExample( # 9
|
||||
"",
|
||||
"Build plot in pieces (continued)",
|
||||
"and add to it later.",
|
||||
[:(
|
||||
begin
|
||||
@ -314,7 +314,7 @@ const _examples = PlotExample[
|
||||
],
|
||||
),
|
||||
PlotExample( # 18
|
||||
"",
|
||||
"Adding to subplots (continued)",
|
||||
"",
|
||||
[:(
|
||||
begin
|
||||
|
||||
@ -4,8 +4,7 @@ legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax, inout)
|
||||
```
|
||||
|
||||
Return `(x,y)` at an angle `theta` degrees from
|
||||
`(xcenter,ycenter)` on a rectangle defined by (`xmin`,
|
||||
`xmax`, `ymin`, `ymax`).
|
||||
`(xcenter,ycenter)` on a rectangle defined by (`xmin`, `xmax`, `ymin`, `ymax`).
|
||||
"""
|
||||
function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax)
|
||||
(s, c) = sincosd(theta)
|
||||
|
||||
@ -472,10 +472,10 @@ yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
|
||||
|
||||
"Specify x axis attributes for an existing plot"
|
||||
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
|
||||
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||
|
||||
"Specify y axis attributes for an existing plot"
|
||||
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
|
||||
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
|
||||
|
||||
@specialize
|
||||
|
||||
@ -377,8 +377,7 @@ nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
|
||||
function nansplit(v::AVec)
|
||||
vs = Vector{eltype(v)}[]
|
||||
while true
|
||||
idx = findfirst(isnan, v)
|
||||
if idx <= 0
|
||||
if (idx = findfirst(isnan, v)) === nothing
|
||||
# no nans
|
||||
push!(vs, v)
|
||||
break
|
||||
|
||||
398
test/runtests.jl
398
test/runtests.jl
@ -37,6 +37,276 @@ end
|
||||
Plots.use_local_dependencies[] = temp
|
||||
end
|
||||
|
||||
@testset "Utils" begin
|
||||
zipped = (
|
||||
[(1, 2)],
|
||||
[("a", "b")],
|
||||
[(1, "a"), (2, "b")],
|
||||
[(1, 2), (3, 4)],
|
||||
[(1, 2, 3), (3, 4, 5)],
|
||||
[(1, 2, 3, 4), (3, 4, 5, 6)],
|
||||
[(1, 2.0), (missing, missing)],
|
||||
[(1, missing), (missing, "a")],
|
||||
[(missing, missing)],
|
||||
[(missing, missing, missing), ("a", "b", "c")],
|
||||
)
|
||||
for z in zipped
|
||||
@test isequal(collect(zip(Plots.RecipesPipeline.unzip(z)...)), z)
|
||||
@test isequal(
|
||||
collect(zip(Plots.RecipesPipeline.unzip(GeometryBasics.Point.(z))...)),
|
||||
z,
|
||||
)
|
||||
end
|
||||
op1 = Plots.process_clims((1.0, 2.0))
|
||||
op2 = Plots.process_clims((1, 2.0))
|
||||
data = randn(100, 100)
|
||||
@test op1(data) == op2(data)
|
||||
@test Plots.process_clims(nothing) ==
|
||||
Plots.process_clims(missing) ==
|
||||
Plots.process_clims(:auto)
|
||||
|
||||
@test (==)(
|
||||
Plots.texmath2unicode(
|
||||
raw"Equation $y = \alpha \cdot x + \beta$ and eqn $y = \sin(x)^2$",
|
||||
),
|
||||
raw"Equation y = α ⋅ x + β and eqn y = sin(x)²",
|
||||
)
|
||||
|
||||
@test Plots.isvector([1, 2])
|
||||
@test !Plots.isvector(nothing)
|
||||
@test Plots.ismatrix([1 2; 3 4])
|
||||
@test !Plots.ismatrix(nothing)
|
||||
@test Plots.isscalar(1.0)
|
||||
@test !Plots.isscalar(nothing)
|
||||
@test Plots.tovec([]) isa AbstractVector
|
||||
@test Plots.tovec(nothing) isa AbstractVector
|
||||
@test Plots.anynan(1, 3, (1, NaN, 3))
|
||||
@test Plots.allnan(1, 2, (NaN, NaN, 1))
|
||||
@test Plots.makevec([]) isa AbstractVector
|
||||
@test Plots.makevec(1) isa AbstractVector
|
||||
@test Plots.maketuple(1) == (1, 1)
|
||||
@test Plots.maketuple((1, 1)) == (1, 1)
|
||||
@test Plots.ok(1, 2)
|
||||
@test !Plots.ok(1, 2, NaN)
|
||||
@test Plots.ok((1, 2, 3))
|
||||
@test !Plots.ok((1, 2, NaN))
|
||||
@test Plots.nansplit([1, 2, NaN, 3, 4]) == [[1.0, 2.0], [3.0, 4.0]]
|
||||
@test Plots.nanvcat([1, NaN]) |> length == 4
|
||||
|
||||
@test Plots.nop() === nothing
|
||||
@test_throws ErrorException Plots.notimpl()
|
||||
|
||||
@test Plots.inch2px(1) isa AbstractFloat
|
||||
@test Plots.px2inch(1) isa AbstractFloat
|
||||
@test Plots.inch2mm(1) isa AbstractFloat
|
||||
@test Plots.mm2inch(1) isa AbstractFloat
|
||||
@test Plots.px2mm(1) isa AbstractFloat
|
||||
@test Plots.mm2px(1) isa AbstractFloat
|
||||
|
||||
p = plot()
|
||||
@test xlims() isa Tuple
|
||||
@test ylims() isa Tuple
|
||||
@test zlims() isa Tuple
|
||||
|
||||
Plots.makekw(foo = 1, bar = 2) isa Dict
|
||||
|
||||
@test_throws ErrorException Plots.inline()
|
||||
@test_throws ErrorException Plots._do_plot_show(plot(), :inline)
|
||||
@test_throws ErrorException Plots.dumpcallstack()
|
||||
|
||||
Plots.debugplots(true)
|
||||
Plots.debugplots(false)
|
||||
Plots.debugshow(devnull, nothing)
|
||||
Plots.debugshow(devnull, [1])
|
||||
|
||||
p = plot(1)
|
||||
push!(p, 1.5)
|
||||
push!(p, 1, 1.5)
|
||||
# append!(p, [1., 2.])
|
||||
append!(p, 1, 2.5, 2.5)
|
||||
push!(p, (1.5, 2.5))
|
||||
push!(p, 1, (1.5, 2.5))
|
||||
append!(p, (1.5, 2.5))
|
||||
append!(p, 1, (1.5, 2.5))
|
||||
|
||||
p = plot([1, 2, 3], [4, 5, 6])
|
||||
@test Plots.xmin(p) == 1
|
||||
@test Plots.xmax(p) == 3
|
||||
@test Plots.ignorenan_extrema(p) == (1, 3)
|
||||
|
||||
@test Plots.get_attr_symbol(:x, "lims") == :xlims
|
||||
@test Plots.get_attr_symbol(:x, :lims) == :xlims
|
||||
|
||||
@testset "NaN-separated Segments" begin
|
||||
segments(args...) = collect(iter_segments(args...))
|
||||
|
||||
nan10 = fill(NaN, 10)
|
||||
@test segments(11:20) == [1:10]
|
||||
@test segments([NaN]) == []
|
||||
@test segments(nan10) == []
|
||||
@test segments([nan10; 1:5]) == [11:15]
|
||||
@test segments([1:5; nan10]) == [1:5]
|
||||
@test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30]
|
||||
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
|
||||
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Axes" begin
|
||||
p = plot()
|
||||
axis = p.subplots[1][:xaxis]
|
||||
@test typeof(axis) == Plots.Axis
|
||||
@test Plots.discrete_value!(axis, "HI") == (0.5, 1)
|
||||
@test Plots.discrete_value!(axis, :yo) == (1.5, 2)
|
||||
@test Plots.ignorenan_extrema(axis) == (0.5, 1.5)
|
||||
@test axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1)
|
||||
|
||||
Plots.discrete_value!(axis, ["x$i" for i in 1:5])
|
||||
Plots.discrete_value!(axis, ["x$i" for i in 0:2])
|
||||
@test Plots.ignorenan_extrema(axis) == (0.5, 7.5)
|
||||
end
|
||||
|
||||
@testset "NoFail" begin
|
||||
# ensure backend with tested display
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
dsp = TextDisplay(IOContext(IOBuffer(), :color => true))
|
||||
|
||||
@testset "plot" begin
|
||||
for plt in [
|
||||
histogram([1, 0, 0, 0, 0, 0]),
|
||||
plot([missing]),
|
||||
plot([missing, missing]),
|
||||
plot(fill(missing, 10)),
|
||||
plot([missing; 1:4]),
|
||||
plot([fill(missing, 10); 1:4]),
|
||||
plot([1 1; 1 missing]),
|
||||
plot(["a" "b"; missing "d"], [1 2; 3 4]),
|
||||
]
|
||||
display(dsp, plt)
|
||||
end
|
||||
@test_nowarn plot(x -> x^2, 0, 2)
|
||||
end
|
||||
|
||||
@testset "bar" begin
|
||||
p = bar([3, 2, 1], [1, 2, 3])
|
||||
@test p isa Plots.Plot
|
||||
@test display(dsp, p) isa Nothing
|
||||
end
|
||||
|
||||
@testset "gui" begin
|
||||
open(tempname(), "w") do io
|
||||
redirect_stdout(io) do
|
||||
gui(plot())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Coverage" begin
|
||||
@testset "themes" begin
|
||||
p = showtheme(:dark)
|
||||
@test p isa Plots.Plot
|
||||
end
|
||||
|
||||
@testset "plotattr" begin
|
||||
tmp = tempname()
|
||||
open(tmp, "w") do io
|
||||
redirect_stdout(io) do
|
||||
plotattr("seriestype")
|
||||
plotattr(:Plot)
|
||||
plotattr()
|
||||
end
|
||||
end
|
||||
str = join(readlines(tmp), "")
|
||||
@test occursin("seriestype", str)
|
||||
@test occursin("Plot attributes", str)
|
||||
end
|
||||
|
||||
@testset "legend" begin
|
||||
@test isa(
|
||||
Plots.legend_pos_from_angle(20, 0.0, 0.5, 1.0, 0.0, 0.5, 1.0),
|
||||
NTuple{2,<:AbstractFloat},
|
||||
)
|
||||
@test Plots.legend_anchor_index(-1) == 1
|
||||
@test Plots.legend_anchor_index(+0) == 2
|
||||
@test Plots.legend_anchor_index(+1) == 3
|
||||
|
||||
@test Plots.legend_angle(:foo_bar) == (45, :inner)
|
||||
@test Plots.legend_angle(20.0) ==
|
||||
Plots.legend_angle((20.0, :inner)) ==
|
||||
(20.0, :inner)
|
||||
@test Plots.legend_angle((20.0, 10.0)) == (20.0, 10.0)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Output" begin
|
||||
@test Plots.defaultOutputFormat(plot()) == "png"
|
||||
@test Plots.addExtension("foo", "bar") == "foo.bar"
|
||||
|
||||
fn = tempname()
|
||||
gr()
|
||||
let p = plot()
|
||||
Plots.png(p, fn)
|
||||
Plots.png(fn)
|
||||
savefig(p, "$fn.png")
|
||||
savefig("$fn.png")
|
||||
|
||||
Plots.pdf(p, fn)
|
||||
Plots.pdf(fn)
|
||||
savefig(p, "$fn.pdf")
|
||||
savefig("$fn.pdf")
|
||||
|
||||
Plots.ps(p, fn)
|
||||
Plots.ps(fn)
|
||||
savefig(p, "$fn.ps")
|
||||
savefig("$fn.ps")
|
||||
|
||||
Plots.svg(p, fn)
|
||||
Plots.svg(fn)
|
||||
savefig(p, "$fn.svg")
|
||||
savefig("$fn.svg")
|
||||
end
|
||||
|
||||
if Sys.islinux()
|
||||
pgfplotsx()
|
||||
let p = plot()
|
||||
Plots.tex(p, fn)
|
||||
Plots.tex(fn)
|
||||
savefig(p, "$fn.tex")
|
||||
savefig("$fn.tex")
|
||||
end
|
||||
end
|
||||
|
||||
unicodeplots()
|
||||
let p = plot()
|
||||
Plots.txt(p, fn)
|
||||
Plots.txt(fn)
|
||||
savefig(p, "$fn.txt")
|
||||
savefig("$fn.txt")
|
||||
end
|
||||
|
||||
plotlyjs()
|
||||
let p = plot()
|
||||
Plots.html(p, fn)
|
||||
Plots.html(fn)
|
||||
savefig(p, "$fn.html")
|
||||
savefig("$fn.html")
|
||||
|
||||
if Sys.islinux()
|
||||
Plots.eps(p, fn)
|
||||
Plots.eps(fn)
|
||||
savefig(p, "$fn.eps")
|
||||
savefig("$fn.eps")
|
||||
end
|
||||
end
|
||||
|
||||
@test_throws ErrorException savefig("$fn.foo")
|
||||
end
|
||||
|
||||
gr() # reset to default backend
|
||||
|
||||
for fn in (
|
||||
"test_args.jl",
|
||||
"test_defaults.jl",
|
||||
@ -52,6 +322,7 @@ for fn in (
|
||||
"test_hdf5plots.jl",
|
||||
"test_pgfplotsx.jl",
|
||||
"test_plotly.jl",
|
||||
"test_animations.jl",
|
||||
)
|
||||
@testset "$fn" begin
|
||||
include(fn)
|
||||
@ -117,106 +388,29 @@ const PLOTS_IMG_TOL = parse(Float64, get(ENV, "PLOTS_IMG_TOL", is_ci() ? "1e-4"
|
||||
|
||||
##
|
||||
|
||||
@testset "Axes" begin
|
||||
p = plot()
|
||||
axis = p.subplots[1][:xaxis]
|
||||
@test typeof(axis) == Plots.Axis
|
||||
@test Plots.discrete_value!(axis, "HI") == (0.5, 1)
|
||||
@test Plots.discrete_value!(axis, :yo) == (1.5, 2)
|
||||
@test Plots.ignorenan_extrema(axis) == (0.5, 1.5)
|
||||
@test axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1)
|
||||
|
||||
Plots.discrete_value!(axis, ["x$i" for i in 1:5])
|
||||
Plots.discrete_value!(axis, ["x$i" for i in 0:2])
|
||||
@test Plots.ignorenan_extrema(axis) == (0.5, 7.5)
|
||||
end
|
||||
|
||||
@testset "NoFail" begin
|
||||
# ensure backend with tested display
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
dsp = TextDisplay(IOContext(IOBuffer(), :color => true))
|
||||
|
||||
@testset "Plot" begin
|
||||
plots = [
|
||||
histogram([1, 0, 0, 0, 0, 0]),
|
||||
plot([missing]),
|
||||
plot([missing, missing]),
|
||||
plot(fill(missing, 10)),
|
||||
plot([missing; 1:4]),
|
||||
plot([fill(missing, 10); 1:4]),
|
||||
plot([1 1; 1 missing]),
|
||||
plot(["a" "b"; missing "d"], [1 2; 3 4]),
|
||||
]
|
||||
for plt in plots
|
||||
display(dsp, plt)
|
||||
end
|
||||
@test_nowarn plot(x -> x^2, 0, 2)
|
||||
end
|
||||
|
||||
@testset "Bar" begin
|
||||
p = bar([3, 2, 1], [1, 2, 3])
|
||||
@test p isa Plots.Plot
|
||||
@test display(dsp, p) isa Nothing
|
||||
end
|
||||
end
|
||||
|
||||
@testset "EmptyAnim" begin
|
||||
anim = @animate for i in []
|
||||
end
|
||||
|
||||
@test_throws ArgumentError gif(anim)
|
||||
end
|
||||
|
||||
@testset "NaN-separated Segments" begin
|
||||
segments(args...) = collect(iter_segments(args...))
|
||||
|
||||
nan10 = fill(NaN, 10)
|
||||
@test segments(11:20) == [1:10]
|
||||
@test segments([NaN]) == []
|
||||
@test segments(nan10) == []
|
||||
@test segments([nan10; 1:5]) == [11:15]
|
||||
@test segments([1:5; nan10]) == [1:5]
|
||||
@test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30]
|
||||
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
|
||||
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
|
||||
end
|
||||
|
||||
@testset "Utils" begin
|
||||
zipped = (
|
||||
[(1, 2)],
|
||||
[("a", "b")],
|
||||
[(1, "a"), (2, "b")],
|
||||
[(1, 2), (3, 4)],
|
||||
[(1, 2, 3), (3, 4, 5)],
|
||||
[(1, 2, 3, 4), (3, 4, 5, 6)],
|
||||
[(1, 2.0), (missing, missing)],
|
||||
[(1, missing), (missing, "a")],
|
||||
[(missing, missing)],
|
||||
[(missing, missing, missing), ("a", "b", "c")],
|
||||
)
|
||||
for z in zipped
|
||||
@test isequal(collect(zip(Plots.RecipesPipeline.unzip(z)...)), z)
|
||||
@test isequal(
|
||||
collect(zip(Plots.RecipesPipeline.unzip(GeometryBasics.Point.(z))...)),
|
||||
z,
|
||||
@testset "Examples" begin
|
||||
if Sys.islinux()
|
||||
backends = (
|
||||
:unicodeplots,
|
||||
:pgfplotsx,
|
||||
:inspectdr,
|
||||
:plotlyjs,
|
||||
:gaston,
|
||||
# :pyplot, # FIXME: fails with system matplotlib
|
||||
)
|
||||
only = setdiff(
|
||||
1:length(Plots._examples),
|
||||
(Plots._backend_skips[be] for be in backends)...,
|
||||
)
|
||||
for be in backends
|
||||
@info be
|
||||
for (i, p) in Plots.test_examples(be, only = only, disp = false)
|
||||
fn = tempname() * ".png"
|
||||
png(p, fn)
|
||||
@test filesize(fn) > 1_000
|
||||
end
|
||||
end
|
||||
end
|
||||
op1 = Plots.process_clims((1.0, 2.0))
|
||||
op2 = Plots.process_clims((1, 2.0))
|
||||
data = randn(100, 100)
|
||||
@test op1(data) == op2(data)
|
||||
@test Plots.process_clims(nothing) ==
|
||||
Plots.process_clims(missing) ==
|
||||
Plots.process_clims(:auto)
|
||||
|
||||
@test (==)(
|
||||
Plots.texmath2unicode(
|
||||
raw"Equation $y = \alpha \cdot x + \beta$ and eqn $y = \sin(x)^2$",
|
||||
),
|
||||
raw"Equation y = α ⋅ x + β and eqn y = sin(x)²",
|
||||
)
|
||||
end
|
||||
|
||||
@testset "Backends" begin
|
||||
@ -230,24 +424,32 @@ end
|
||||
p = plot(rand(10))
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = bar(randn(10))
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot([1, 2], [3, 4])
|
||||
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
|
||||
hline!(p, [3.1])
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
|
||||
hline!(p, [3.1])
|
||||
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
|
||||
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
|
||||
hline!(p, [3.1])
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot((plot(i) for i in 1:4)..., layout = (2, 2))
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
end
|
||||
|
||||
@testset "GR" begin
|
||||
|
||||
61
test/test_animations.jl
Normal file
61
test/test_animations.jl
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
@testset "Empty anim" begin
|
||||
anim = @animate for i in []
|
||||
end
|
||||
@test_throws ArgumentError gif(anim)
|
||||
end
|
||||
|
||||
@userplot CirclePlot
|
||||
@recipe function f(cp::CirclePlot)
|
||||
x, y, i = cp.args
|
||||
n = length(x)
|
||||
inds = circshift(1:n, 1 - i)
|
||||
linewidth --> range(0, 10, length = n)
|
||||
seriesalpha --> range(0, 1, length = n)
|
||||
aspect_ratio --> 1
|
||||
label --> false
|
||||
x[inds], y[inds]
|
||||
end
|
||||
|
||||
@testset "Circle plot" begin
|
||||
n = 10
|
||||
t = range(0, 2π, length = n)
|
||||
x = sin.(t)
|
||||
y = cos.(t)
|
||||
|
||||
anim = @animate for i in 1:n
|
||||
circleplot(x, y, i)
|
||||
end
|
||||
@test filesize(gif(anim).filename) > 10_000
|
||||
@test filesize(mov(anim).filename) > 10_000
|
||||
@test filesize(mp4(anim).filename) > 10_000
|
||||
@test filesize(webm(anim).filename) > 10_000
|
||||
|
||||
@gif for i in 1:n
|
||||
circleplot(x, y, i, line_z = 1:n, cbar = false, framestyle = :zerolines)
|
||||
end every 5
|
||||
end
|
||||
|
||||
@testset "html" begin
|
||||
p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1))
|
||||
anim = Animation()
|
||||
for x in range(0, stop = 2π, length = 10)
|
||||
push!(p, x, Float64[sin(x), cos(x)])
|
||||
frame(anim)
|
||||
end
|
||||
|
||||
agif = gif(anim)
|
||||
html = tempname() * ".html"
|
||||
open(html, "w") do io
|
||||
show(io, MIME("text/html"), agif)
|
||||
end
|
||||
@test filesize(html) > 10_000
|
||||
@test showable(MIME("image/gif"), agif)
|
||||
|
||||
agif = mp4(anim)
|
||||
html = tempname() * ".html"
|
||||
open(html, "w") do io
|
||||
show(io, MIME("text/html"), agif)
|
||||
end
|
||||
@test filesize(html) > 10_000
|
||||
end
|
||||
@ -3,6 +3,9 @@ using Plots, Test
|
||||
@testset "Shapes" begin
|
||||
@testset "Type" begin
|
||||
square = Shape([(0, 0.0), (1, 0.0), (1, 1.0), (0, 1.0)])
|
||||
@test Plots.get_xs(square) == [0, 1, 1, 0]
|
||||
@test Plots.get_ys(square) == [0, 0, 1, 1]
|
||||
@test Plots.vertices(square) == [(0, 0), (1, 0), (1, 1), (0, 1)]
|
||||
@test isa(square, Shape{Int64,Float64})
|
||||
@test coords(square) isa Tuple{Vector{S},Vector{T}} where {T,S}
|
||||
end
|
||||
@ -58,6 +61,25 @@ using Plots, Test
|
||||
@test_nowarn p = plot(myshapes)
|
||||
@test p[1][1][:seriestype] == :shape
|
||||
end
|
||||
|
||||
@testset "Misc" begin
|
||||
@test Plots.weave([1, 3], [2, 4]) == collect(1:4)
|
||||
@test Plots.makeshape(3) isa Plots.Shape
|
||||
@test Plots.makestar(3) isa Plots.Shape
|
||||
@test Plots.makecross() isa Plots.Shape
|
||||
@test Plots.makearrowhead(10.0) isa Plots.Shape
|
||||
|
||||
@test Plots.rotate(1.0, 2.0, 5.0, (0, 0)) isa Tuple
|
||||
|
||||
star = Plots.makestar(3)
|
||||
star_scaled = Plots.scale(star, 0.5)
|
||||
|
||||
Plots.scale!(star, 0.5)
|
||||
@test Plots.get_xs(star) == Plots.get_xs(star_scaled)
|
||||
@test Plots.get_ys(star) == Plots.get_ys(star_scaled)
|
||||
|
||||
@test Plots.extrema_plus_buffer([1, 2], 0.1) == (0.9, 2.1)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Brush" begin
|
||||
@ -82,6 +104,39 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Text" begin
|
||||
t = Plots.PlotText("foo")
|
||||
f = Plots.font()
|
||||
|
||||
@test Plots.PlotText(nothing).str == "nothing"
|
||||
@test length(t) == 3
|
||||
@test text(t).str == "foo"
|
||||
@test text(t, f).str == "foo"
|
||||
@test text("bar", f).str == "bar"
|
||||
@test text(true).str == "true"
|
||||
end
|
||||
|
||||
@testset "Annotations" begin
|
||||
ann = Plots.series_annotations(missing)
|
||||
|
||||
@test Plots.series_annotations(["1" "2"; "3" "4"]) isa AbstractMatrix
|
||||
@test Plots.series_annotations(10).strs[1].str == "10"
|
||||
@test Plots.series_annotations(nothing) === nothing
|
||||
@test Plots.series_annotations(ann) == ann
|
||||
|
||||
@test Plots.annotations(["1" "2"; "3" "4"]) isa AbstractMatrix
|
||||
@test Plots.annotations(ann) == ann
|
||||
@test Plots.annotations([ann]) == [ann]
|
||||
@test Plots.annotations(nothing) == []
|
||||
|
||||
t = Plots.text("foo")
|
||||
sp = plot(1)[1]
|
||||
@test Plots.locate_annotation(sp, 1, 2, t) == (1, 2, t)
|
||||
@test Plots.locate_annotation(sp, 1, 2, 3, t) == (1, 2, 3, t)
|
||||
@test Plots.locate_annotation(sp, (0.1, 0.2), t) isa Tuple
|
||||
@test Plots.locate_annotation(sp, (0.1, 0.2, 0.3), t) isa Tuple
|
||||
end
|
||||
|
||||
@testset "Fonts" begin
|
||||
@testset "Scaling" begin
|
||||
sizesToCheck = [
|
||||
@ -158,3 +213,9 @@ end
|
||||
@test pos == (0.1, 0.5)
|
||||
@test txt.str == "(a)"
|
||||
end
|
||||
|
||||
@testset "Bezier" begin
|
||||
curve = Plots.BezierCurve([Plots.P2(0.0, 0.0), Plots.P2(0.5, 1.0), Plots.P2(1.0, 0.0)])
|
||||
@test curve(0.75) == Plots.P2(0.75, 0.375)
|
||||
@test length(coords(curve, 10)) == 10
|
||||
end
|
||||
|
||||
@ -32,3 +32,67 @@ end
|
||||
@test p[2][:framestyle] === :grid
|
||||
@test p[3][:framestyle] === :none
|
||||
end
|
||||
|
||||
@testset "Coverage" begin
|
||||
p = plot((plot(i) for i in 1:4)..., layout = (2, 2))
|
||||
|
||||
sp = p[end]
|
||||
@test sp isa Plots.Subplot
|
||||
@test size(sp) == (1, 1)
|
||||
@test length(sp) == 1
|
||||
@test sp[1, 1] == sp
|
||||
@test Plots.get_subplot(p, UInt32(4)) == sp
|
||||
@test Plots.series_list(sp) |> first |> Plots.get_subplot isa Plots.Subplot
|
||||
@test Plots.get_subplot(p, keys(p.spmap) |> first) isa Plots.Subplot
|
||||
|
||||
gl = p[2, 2]
|
||||
@test gl isa Plots.GridLayout
|
||||
@test length(gl) == 1
|
||||
@test size(gl) == (1, 1)
|
||||
@test Plots.layout_args(gl) == (gl, 1)
|
||||
|
||||
@test size(p, 1) == 2
|
||||
@test size(p, 2) == 2
|
||||
@test size(p) === (2, 2)
|
||||
@test ndims(p) == 2
|
||||
|
||||
@test p[1][end] isa Plots.Series
|
||||
show(devnull, p[1])
|
||||
|
||||
@test Plots.getplot(p) == p
|
||||
@test Plots.getattr(p) == p.attr
|
||||
@test Plots.backend_object(p) == p.o
|
||||
@test occursin("Plot", string(p))
|
||||
print(devnull, p)
|
||||
|
||||
@test Plots.to_pixels(1Plots.mm) isa AbstractFloat
|
||||
@test Plots.ispositive(1Plots.mm)
|
||||
@test size(Plots.defaultbox) == (0Plots.mm, 0Plots.mm)
|
||||
show(devnull, Plots.defaultbox)
|
||||
show(devnull, p.layout)
|
||||
|
||||
@test Plots.make_measure_hor(1Plots.mm) == 1Plots.mm
|
||||
@test Plots.make_measure_vert(1Plots.mm) == 1Plots.mm
|
||||
|
||||
@test Plots.parent(p.layout) isa Plots.RootLayout
|
||||
show(devnull, Plots.parent_bbox(p.layout))
|
||||
|
||||
rl = Plots.RootLayout()
|
||||
show(devnull, rl)
|
||||
@test parent(rl) === nothing
|
||||
@test Plots.parent_bbox(rl) == Plots.defaultbox
|
||||
@test Plots.bbox(rl) == Plots.defaultbox
|
||||
|
||||
el = Plots.EmptyLayout()
|
||||
@test Plots.update_position!(el) === nothing
|
||||
@test size(el) == (0, 0)
|
||||
@test length(el) == 0
|
||||
@test el[1, 1] === nothing
|
||||
|
||||
@test Plots.left(el) == 0Plots.mm
|
||||
@test Plots.top(el) == 0Plots.mm
|
||||
@test Plots.right(el) == 0Plots.mm
|
||||
@test Plots.bottom(el) == 0Plots.mm
|
||||
|
||||
@test_throws ErrorException Plots.layout_args(nothing)
|
||||
end
|
||||
|
||||
@ -7,42 +7,132 @@ using Plots, Test
|
||||
xlims!((1, 20))
|
||||
@test xlims(p) == (1, 20)
|
||||
|
||||
xlims!(p, (1, 21))
|
||||
@test xlims(p) == (1, 21)
|
||||
|
||||
ylims!((-1, 1))
|
||||
@test ylims(p) == (-1, 1)
|
||||
|
||||
ylims!(p, (-2, 2))
|
||||
@test ylims(p) == (-2, 2)
|
||||
|
||||
zlims!((-1, 1))
|
||||
@test zlims(p) == (-1, 1)
|
||||
|
||||
zlims!(p, (-2, 2))
|
||||
@test zlims(p) == (-2, 2)
|
||||
|
||||
xlims!(-1, 11)
|
||||
@test xlims(p) == (-1, 11)
|
||||
|
||||
xlims!(p, -2, 12)
|
||||
@test xlims(p) == (-2, 12)
|
||||
|
||||
ylims!((-10, 10))
|
||||
@test ylims(p) == (-10, 10)
|
||||
|
||||
ylims!(p, (-11, 9))
|
||||
@test ylims(p) == (-11, 9)
|
||||
|
||||
zlims!((-10, 10))
|
||||
@test zlims(p) == (-10, 10)
|
||||
|
||||
zlims!(p, (-9, 8))
|
||||
@test zlims(p) == (-9, 8)
|
||||
end
|
||||
|
||||
@testset "Set Title / Labels" begin
|
||||
p = plot()
|
||||
title!(p, "Foo")
|
||||
sp = p[1]
|
||||
@test sp[:title] == "Foo"
|
||||
xlabel!(p, "xlabel")
|
||||
@test sp[:xaxis][:guide] == "xlabel"
|
||||
ylabel!(p, "ylabel")
|
||||
@test sp[:yaxis][:guide] == "ylabel"
|
||||
end
|
||||
|
||||
@testset "Misc" begin
|
||||
p = plot()
|
||||
sp = p[1]
|
||||
|
||||
xflip!(p)
|
||||
@test sp[:xaxis][:flip]
|
||||
|
||||
yflip!(p)
|
||||
@test sp[:yaxis][:flip]
|
||||
|
||||
xgrid!(p, true)
|
||||
@test sp[:xaxis][:grid]
|
||||
|
||||
xgrid!(p, false)
|
||||
@test !sp[:xaxis][:grid]
|
||||
|
||||
ygrid!(p, true)
|
||||
@test sp[:yaxis][:grid]
|
||||
|
||||
ygrid!(p, false)
|
||||
@test !sp[:yaxis][:grid]
|
||||
|
||||
ann = [(7, 3, "(7,3)"), (3, 7, text("hey", 14, :left, :top, :green))]
|
||||
annotate!(p, ann)
|
||||
annotate!(p, ann...)
|
||||
|
||||
xaxis!(p, true)
|
||||
@test sp[:xaxis][:showaxis]
|
||||
|
||||
xaxis!(p, false)
|
||||
@test !sp[:xaxis][:showaxis]
|
||||
|
||||
yaxis!(p, true)
|
||||
@test sp[:yaxis][:showaxis]
|
||||
|
||||
yaxis!(p, false)
|
||||
@test !sp[:yaxis][:showaxis]
|
||||
|
||||
p = plot3d([1, 2], [1, 2], [1, 2])
|
||||
plot3d!(p, [3, 4], [3, 4], [3, 4])
|
||||
@test Plots.series_list(p[1])[1][:seriestype] == :path3d
|
||||
end
|
||||
|
||||
@testset "Set Ticks" begin
|
||||
p = plot([0, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
sp = p[1]
|
||||
|
||||
xticks = 2:6
|
||||
xticks!(xticks)
|
||||
@test Plots.get_subplot(current(), 1).attr[:xaxis][:ticks] == xticks
|
||||
@test sp.attr[:xaxis][:ticks] == xticks
|
||||
|
||||
xticks = 1:5
|
||||
xticks!(p, xticks)
|
||||
@test sp.attr[:xaxis][:ticks] == xticks
|
||||
|
||||
yticks = 0.2:0.1:0.7
|
||||
yticks!(yticks)
|
||||
@test Plots.get_subplot(current(), 1).attr[:yaxis][:ticks] == yticks
|
||||
@test sp.attr[:yaxis][:ticks] == yticks
|
||||
|
||||
yticks = 0.1:0.5
|
||||
yticks!(p, yticks)
|
||||
@test sp.attr[:yaxis][:ticks] == yticks
|
||||
|
||||
xticks = [5, 6, 7.5]
|
||||
xlabels = ["a", "b", "c"]
|
||||
|
||||
xticks!(xticks, xlabels)
|
||||
@test Plots.get_subplot(current(), 1).attr[:xaxis][:ticks] == (xticks, xlabels)
|
||||
@test sp.attr[:xaxis][:ticks] == (xticks, xlabels)
|
||||
|
||||
xticks = [5, 2]
|
||||
xlabels = ["b", "a"]
|
||||
xticks!(p, xticks, xlabels)
|
||||
@test sp.attr[:xaxis][:ticks] == (xticks, xlabels)
|
||||
|
||||
yticks = [0.5, 0.6, 0.75]
|
||||
ylabels = ["z", "y", "x"]
|
||||
yticks!(yticks, ylabels)
|
||||
@test Plots.get_subplot(current(), 1).attr[:yaxis][:ticks] == (yticks, ylabels)
|
||||
@test sp.attr[:yaxis][:ticks] == (yticks, ylabels)
|
||||
|
||||
yticks = [0.5, 0.1]
|
||||
ylabels = ["z", "y"]
|
||||
yticks!(p, yticks, ylabels)
|
||||
@test sp.attr[:yaxis][:ticks] == (yticks, ylabels)
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user