Skip to content

Commit 2e5d6fb

Browse files
committed
move plotting to package extensions
1 parent 526001d commit 2e5d6fb

File tree

6 files changed

+86
-58
lines changed

6 files changed

+86
-58
lines changed

Project.toml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "BasisFunctions"
22
uuid = "4343a256-5453-507d-8aad-01a9d7189916"
33
authors = ["Daan Huybrechs <daan.huybrechs@kuleuven.be>"]
4-
version = "0.6.4"
4+
version = "0.6.5"
55

66
[deps]
77
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
@@ -19,17 +19,23 @@ IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
1919
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
2020
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
2121
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
22-
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
2322
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
2423
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
25-
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
2624
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
2725
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2826
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
2927
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
3028
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3129
ToeplitzMatrices = "c751599d-da0a-543b-9d20-d0a503d91d24"
3230

31+
[weakdeps]
32+
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
33+
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
34+
35+
[extensions]
36+
BasisFunctionsRecipesBaseExt = "RecipesBase"
37+
BasisFunctionsPGFPlotsXExt = "PGFPlotsX"
38+
3339
[compat]
3440
BlockArrays = "0.16"
3541
CompositeTypes = "0.1.3"
@@ -52,7 +58,7 @@ Reexport = "1.0"
5258
SpecialFunctions = "1.0, 2.0"
5359
StaticArrays = "1.4"
5460
ToeplitzMatrices = "0.7"
55-
julia = "1.6"
61+
julia = "1.9"
5662

5763
[extras]
5864
Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
@@ -61,4 +67,4 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
6167
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
6268

6369
[targets]
64-
test = ["Plots", "Random", "Calculus", "DoubleFloats"]
70+
test = ["PGFPlotsX", "Plots", "Random", "RecipesBase", "Calculus", "DoubleFloats"]

src/util/display/pgfplots.jl renamed to ext/BasisFunctionsPGFPlotsXExt/BasisFunctionsPGFPlotsXExt.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
module BasisFunctionsPGFPlotsXExt
2+
3+
using BasisFunctions, PGFPlotsX
14

2-
using PGFPlotsX
35
import PGFPlotsX: Plot, PlotInc, Options, Axis
46

7+
using BasisFunctions:
8+
plotgrid
9+
510
for F in (:Expansion,)
611
@eval begin
712
Axis(F::$F, trailing...; opts...) =
@@ -29,12 +34,12 @@ for plot in (:Plot, :PlotInc)
2934
if plot_complex
3035
vals = F.(grid)
3136
options = @pgf {options..., no_markers}
32-
$(plot)(options, Table([grid, BasisFunctions.postprocess(dictionary(F), grid, real.(vals))])),
33-
$(plot)(options, Table([grid, BasisFunctions.postprocess(dictionary(F), grid, imag.(vals))]))
37+
$(plot)(options, Table([grid, BasisFunctions.plot_postprocess(dictionary(F), grid, real.(vals))])),
38+
$(plot)(options, Table([grid, BasisFunctions.plot_postprocess(dictionary(F), grid, imag.(vals))]))
3439
else
3540
vals = real.(F.(grid))
3641
options = @pgf {options..., no_markers}
37-
$(plot)(options, Table([grid, BasisFunctions.postprocess(dictionary(F), grid, vals)]))
42+
$(plot)(options, Table([grid, BasisFunctions.plot_postprocess(dictionary(F), grid, vals)]))
3843
end
3944
end
4045

@@ -51,7 +56,9 @@ for plot in (:Plot, :PlotInc)
5156
grid = plotgrid(dictionary(F), n)
5257
vals = abs.(f.(grid) - F.(grid))
5358
options = @pgf {options..., no_markers}
54-
$(plot)(options, Table([grid, BasisFunctions.postprocess(dictionary(F), grid, vals)]))
59+
$(plot)(options, Table([grid, BasisFunctions.plot_postprocess(dictionary(F), grid, vals)]))
5560
end
5661
end
5762
end
63+
64+
end

src/util/display/recipes.jl renamed to ext/BasisFunctionsRecipesBaseExt/BasisFunctionsRecipesBaseExt.jl

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
module BasisFunctionsRecipesBaseExt
2+
3+
using BasisFunctions, RecipesBase
4+
5+
using BasisFunctions:
6+
AbstractBasisFunction,
7+
Domain2d,
8+
plotgrid,
9+
plot_postprocess
10+
11+
import BasisFunctions:
12+
plotgrid,
13+
plot_postprocess
114

215
## Plotting recipe for a setexpansion:
316
# - determine the plotting grid(depending on the basis)
417
# - evaluate the expansion in the gridpoints (fast if possible)
5-
# - postprocess the data
18+
# - plot_postprocess the data
619

720
@recipe function f(S::Expansion; plot_complex = false, n=200)
821
legend --> false
922
# title --> "Expansion"
1023
grid = plotgrid(dictionary(S), n)
1124
vals = plot_complex ? S.(grid) : real(S.(grid))
12-
grid, postprocess(dictionary(S), grid, vals)
25+
grid, plot_postprocess(dictionary(S), grid, vals)
1326
end
1427

1528
# When a target function is provided, plot the error
@@ -19,7 +32,7 @@ end
1932
# Determine the return type so we know where to sample
2033
origvals = sample(grid, target, codomaintype(S))
2134
vals = abs.(origvals - S.(grid))
22-
dictionary(S), grid, postprocess(dictionary(S), grid, vals)
35+
dictionary(S), grid, plot_postprocess(dictionary(S), grid, vals)
2336
end
2437
# 1D error plot
2538
@recipe function f(S::Dictionary1d, grid::AbstractGrid, vals)
@@ -45,7 +58,7 @@ end
4558
grid = plotgrid(F[i],n)
4659
z = F[i].(grid)
4760
vals = plot_complex ? z : real(z)
48-
grid, postprocess(F[i],grid,vals)
61+
grid, plot_postprocess(F[i],grid,vals)
4962
end
5063
end
5164
nothing
@@ -57,46 +70,11 @@ end
5770
grid = plotgrid(φ,n)
5871
z = φ.(grid)
5972
vals = plot_complex ? z : real(z)
60-
grid, postprocess(φ,grid,vals)
73+
grid, plot_postprocess(φ,grid,vals)
6174
end
6275
nothing
6376
end
6477

65-
#
66-
# For regular Expansions, no postprocessing is needed
67-
function postprocess(S::Dictionary, grid, vals)
68-
D = support(S)
69-
I = grid .∉ Ref(D)
70-
vals[I] .= Inf
71-
vals
72-
end
73-
74-
# For function subsets, revert to the underlying Dictionary for postprocessing
75-
postprocess(S::Subdictionary, grid, vals) = postprocess(superdict(S), grid, vals)
76-
postprocess::AbstractBasisFunction, grid, vals) = postprocess(dictionary(φ), grid, vals)
77-
78-
## Plotting grids
79-
# Always plot on equispaced grids for the best plotting resolution
80-
plotgrid(S::Dictionary1d, n) = EquispacedGrid(n, support(S))
81-
# look at first element by default
82-
plotgrid(S::MultiDict, n) = plotgrid(component(S,1), n)
83-
plotgrid(S::DerivedDict, n) = plotgrid(superdict(S),n)
84-
# NOTE: This only supports multi-dimensional tensor product dicts.
85-
plotgrid(F::TensorProductDict2, n) = plotgrid(component(F,1),n)×plotgrid(component(F,2),n)
86-
plotgrid(F::OperatedDict, n) = plotgrid(superdict(F), n)
87-
plotgrid(F::Subdictionary, n) = plotgrid(superdict(F), n)
88-
plotgrid::AbstractBasisFunction, n) = plotgrid(dictionary(φ), n)
89-
90-
# generic fallback for suitable plotting grids
91-
plotgrid(S::Dictionary, n) = plotgrid_domain(n, support(S))
92-
plotgrid_domain(n::Int, domain::AbstractInterval) = EquispacedGrid(n, domain)
93-
plotgrid_domain(n::Int, domain::ProductDomain) =
94-
productgrid(map(d->plotgrid_domain(n, d), factors(domain))...)
95-
function plotgrid_domain(n::Int, domain)
96-
box = boundingbox(domain)
97-
g = plotgrid_domain(n, box)
98-
MaskedGrid(g, domain)
99-
end
10078

10179
## Split complex plots in real and imaginary parts
10280
# 1D
@@ -140,7 +118,7 @@ end
140118

141119
@recipe function f(dom::Domain2d; n=300, distance=false, xlim=[-1,1], ylim=[-1,1])
142120
seriescolor --> :tempo
143-
seriestype --> :heatmap
121+
seriestype --> :heatmap
144122
aspect_ratio --> 1
145123
colorbar --> false
146124
# xrange = linspace(xlim[1],xlim[2],n)
@@ -153,3 +131,5 @@ end
153131
plotdata = distance ? dist.(grid, Ref(dom)) : in.(grid, Ref(dom))
154132
collect(xrange),collect(yrange),plotdata'
155133
end
134+
135+
end

src/BasisFunctions.jl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ using DomainSets, DomainIntegrals
1111
using CompositeTypes, CompositeTypes.Display
1212

1313
using QuadGK, Base.Cartesian
14-
using RecipesBase
1514

1615
using Reexport
1716

@@ -295,9 +294,6 @@ export ChebyshevT, ChebyshevU,
295294
FastChebyshevTransform, InverseFastChebyshevTransform,
296295
FastChebyshevTransformFFTW, InverseFastChebyshevTransformFFTW
297296

298-
# from util/recipes.jl
299-
export plotgrid, postprocess
300-
301297
# from bases/poly/orthopoly.jl and friends
302298
export Legendre, Jacobi, Laguerre, Hermite,
303299
Monomials, GenericOPS,
@@ -416,8 +412,7 @@ include("bases/poly/ops/hermite.jl")
416412
include("bases/poly/ops/generic_op.jl")
417413
include("bases/poly/ops/specialOPS.jl")
418414

419-
include("util/display/recipes.jl")
420-
include("util/display/pgfplots.jl")
415+
include("util/plot.jl")
421416

422417
include("test/Test.jl")
423418

src/util/plot.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
"Return a grid suitable for plotting a function in the given dictionary."
3+
function plotgrid end
4+
"Process plotting data before it is visualized."
5+
function plot_postprocess end
6+
7+
# For regular Expansions, no postprocessing is needed
8+
function plot_postprocess(S::Dictionary, grid, vals)
9+
D = support(S)
10+
I = grid .∉ Ref(D)
11+
vals[I] .= Inf
12+
vals
13+
end
14+
15+
# For function subsets, revert to the underlying Dictionary for postprocessing
16+
plot_postprocess(S::Subdictionary, grid, vals) = plot_postprocess(superdict(S), grid, vals)
17+
plot_postprocess::AbstractBasisFunction, grid, vals) = plot_postprocess(dictionary(φ), grid, vals)
18+
19+
## Plotting grids
20+
# Always plot on equispaced grids for the best plotting resolution
21+
plotgrid(S::Dictionary1d, n) = EquispacedGrid(n, support(S))
22+
# look at first element by default
23+
plotgrid(S::MultiDict, n) = plotgrid(component(S,1), n)
24+
plotgrid(S::DerivedDict, n) = plotgrid(superdict(S),n)
25+
# NOTE: This only supports multi-dimensional tensor product dicts.
26+
plotgrid(F::TensorProductDict2, n) = plotgrid(component(F,1),n)×plotgrid(component(F,2),n)
27+
plotgrid(F::OperatedDict, n) = plotgrid(superdict(F), n)
28+
plotgrid(F::Subdictionary, n) = plotgrid(superdict(F), n)
29+
plotgrid::AbstractBasisFunction, n) = plotgrid(dictionary(φ), n)
30+
31+
# generic fallback for suitable plotting grids
32+
plotgrid(S::Dictionary, n) = plotgrid_domain(n, support(S))
33+
plotgrid_domain(n::Int, domain::AbstractInterval) = EquispacedGrid(n, domain)
34+
plotgrid_domain(n::Int, domain::ProductDomain) =
35+
productgrid(map(d->plotgrid_domain(n, d), factors(domain))...)
36+
function plotgrid_domain(n::Int, domain)
37+
box = boundingbox(domain)
38+
g = plotgrid_domain(n, box)
39+
MaskedGrid(g, domain)
40+
end

test/test_plots.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using BasisFunctions, BasisFunctions.Test, DomainSets, GridArrays
22

3-
using Test, LinearAlgebra, Plots
3+
using Test, LinearAlgebra, PGFPlotsX, Plots
44

55
delimit("Plots")
66
@testset begin

0 commit comments

Comments
 (0)