Skip to content

Commit c80d51a

Browse files
chmerdonchmerdonpjaap
authored
Tidying up the plotting infrastructure (#66)
* make UnicodePlots the default plotter in all Examples, use GridVisualize recipes * remove test/Project.toml, now handled by extras/targets in main Project.toml * pre-commit update, missing compats * added Term to docs/Project.toml * improved plotting in examples * scalarplot, vectorplots, broken_scalarplot moved from ExtendableFEM to ExtendableFEMBase, Base.depwarns for unicode_gridplot and unicode_scalarplot * removed stale imports, added streamplot, version bump, changelog * documentation * remove debug code * bump to GridVisualize 1.20 --------- Co-authored-by: chmerdon <christian.merdon@wias-berlin.de> Co-authored-by: Patrick Jaap <patrick.jaap@wias-berlin.de>
1 parent 42de0a4 commit c80d51a

13 files changed

Lines changed: 219 additions & 53 deletions

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# CHANGES
22

3-
## v1.6.0
3+
## v1.6.0 April 28, 2026
4+
- unicode plotting extension marked as deprecated (will be removed in next major version), they can be realized now with GridVisualize 1.9 and backend Plotter = UnicdePlots
5+
- added scalarplot, vectorplot and broken_scalarplot defined for FEVectorBlocks (moved from ExtendableFEM)
6+
- updated plotting code in all examples
47
- added Curl2D and Curl3D evaluation for Hdiv
58

69

Project.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
1010
ExtendableGrids = "cfc395e8-590f-11e8-1f13-43a2532b2fa8"
1111
ExtendableSparse = "95c220a8-a1cf-11e9-0c77-dbfce5f500b3"
1212
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
13+
GridVisualize = "5eed8a63-0fb0-45eb-886d-8d5a387d12b8"
1314
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1415
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
1516
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
@@ -25,18 +26,36 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
2526
ExtendableFEMBaseUnicodePlotsExt = ["UnicodePlots"]
2627

2728
[compat]
29+
Aqua = "0.8"
2830
DiffResults = "1"
2931
DifferentiationInterface = "0.7.10"
3032
DocStringExtensions = "0.8,0.9"
33+
ExampleJuggler = "2.2.1"
34+
ExplicitImports = "1"
3135
ExtendableGrids = "1.13.0"
3236
ExtendableSparse = "1.5.1, 2"
3337
ForwardDiff = "0.10.35, 1"
38+
GridVisualize = "1.20"
3439
LinearAlgebra = "1.9"
3540
Polynomials = "2.0.21, 3, 4"
3641
Printf = "1.9"
3742
SparseArrays = "1.9"
3843
SparseConnectivityTracer = "1.1.2"
3944
SparseMatrixColorings = "0.4.22"
4045
SpecialPolynomials = "0.4.9, 0.5"
46+
Term = "2.0.8"
47+
Test = "1"
4148
UnicodePlots = "3.6"
4249
julia = "1.9"
50+
51+
[extras]
52+
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
53+
ExampleJuggler = "3bbe58f8-ed81-4c4e-a134-03e85fcf4a1a"
54+
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
55+
GridVisualize = "5eed8a63-0fb0-45eb-886d-8d5a387d12b8"
56+
Term = "22787eb5-b846-44ae-b979-8e399b8463ab"
57+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
58+
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
59+
60+
[targets]
61+
test = ["Aqua", "ExampleJuggler", "ExplicitImports", "GridVisualize", "Term", "Test", "UnicodePlots"]

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
1212
PlutoStaticHTML = "359b1769-a58e-495b-9770-312e911026ad"
1313
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
1414
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
15+
Term = "22787eb5-b846-44ae-b979-8e399b8463ab"
1516

1617
[compat]
1718
Literate = ">=0.2.7"

examples/Example200_LowLevelPoisson.jl

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ using ExtendableFEMBase
2727
using ExtendableGrids
2828
using ExtendableSparse
2929
using GridVisualize
30-
using UnicodePlots
30+
using UnicodePlots, Term
3131
using Test #
3232

3333
function main(;
3434
maxnref = 8,
3535
order = 2,
36-
Plotter = nothing,
36+
Plotter = UnicodePlots,
3737
mu = 1.0,
3838
rhs = x -> x[1] - x[2]
3939
)
@@ -47,30 +47,27 @@ function main(;
4747
solution, time_assembly, time_solve = solve_poisson_lowlevel(fe_space, mu, rhs)
4848

4949
## loop over uniform refinements + timings
50-
plt = GridVisualizer(; Plotter = Plotter, layout = (1, 1), clear = true, resolution = (500, 500))
50+
plt = GridVisualizer(; Plotter = Plotter, layout = (1, 3), clear = true, resolution = (1200, 400))
5151
loop_allocations = 0
5252
for level in 1:maxnref
5353
X = LinRange(0, 1, 2^level + 1)
5454
time_grid = @elapsed xgrid = simplexgrid(X, X)
5555
time_facenodes = @elapsed xgrid[FaceNodes]
5656
fe_space = FESpace{FEType}(xgrid)
5757
println("\nLEVEL = $level, ndofs = $(fe_space.ndofs)\n")
58-
if level < 4
59-
println(stdout, unicode_gridplot(xgrid))
60-
end
58+
6159
time_dofmap = @elapsed fe_space[CellDofs]
6260
solution, time_assembly, time_solve = solve_poisson_lowlevel(fe_space, mu, rhs)
6361

6462
## plot statistics
6563
println(stdout, barplot(["Grid", "FaceNodes", "celldofs", "Assembly", "Solve"], [time_grid, time_facenodes, time_dofmap, time_assembly, time_solve], title = "Runtimes"))
6664

67-
## plot
68-
if Plotter !== nothing
69-
scalarplot!(plt[1, 1], xgrid, view(solution.entries, 1:num_nodes(xgrid)), limits = (-0.0125, 0.0125))
70-
else
71-
solution_grad = continuify(solution[1], Gradient)
72-
println(stdout, unicode_scalarplot(solution[1]))
73-
end
65+
# plot
66+
scalarplot!(plt[1, 1], solution[1])
67+
scalarplot!(plt[1, 2], solution[1], Gradient; abs = true, clear = true)
68+
vectorplot!(plt[1, 2], solution[1], Gradient; clear = false)
69+
gridplot!(plt[1, 3], xgrid; markersize = 0)
70+
reveal(plt)
7471
end
7572

7673
return solution, plt

examples/Example205_LowLevelSpaceTimePoisson.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ using ExtendableFEMBase
2727
using ExtendableGrids
2828
using ExtendableSparse
2929
using GridVisualize
30-
using UnicodePlots
30+
using UnicodePlots, Term
3131
using Test #
3232

3333
## data for Poisson problem
3434
const μ = (t) -> 1.0e-1 * t + 1 * max(0, (1 - 2 * t))
3535
const f = (x, t) -> sin(3 * pi * x[1]) * 4 * t - cos(3 * pi * x[2]) * 4 * (1 - t)
3636

37-
function main(; dt = 0.01, Tfinal = 1, level = 5, order = 1, Plotter = nothing, produce_movie = false)
37+
function main(; dt = 0.01, Tfinal = 1, level = 5, order = 1, Plotter = UnicodePlots, produce_movie = false)
3838

3939
## Finite element type
4040
FEType_time = H1Pk{1, 1, order}
@@ -72,13 +72,14 @@ function main(; dt = 0.01, Tfinal = 1, level = 5, order = 1, Plotter = nothing,
7272
else
7373
@info "Plotting at five times..."
7474
plot_timesteps = [2, round(Int, length(T) / 4 + 0.25), round(Int, length(T) / 2 + 0.5), round(Int, length(T) - length(T) / 4), FES_time.ndofs]
75-
plt = GridVisualizer(; Plotter = Plotter, layout = (1, length(plot_timesteps)), clear = true, resolution = (200 * length(plot_timesteps), 200))
75+
plt = GridVisualizer(; Plotter = Plotter, layout = (1, length(plot_timesteps)), clear = true, resolution = (300 * length(plot_timesteps), 300))
7676
for tj in 1:length(plot_timesteps)
7777
t = plot_timesteps[tj]
7878
first = (t - 1) * FES_space.ndofs + 1
7979
last = t * FES_space.ndofs
8080
scalarplot!(plt[1, tj], grid_space, view(sol, first:last), title = "t = $(T[t])")
8181
end
82+
reveal(plt)
8283
return sol, plt
8384
end
8485

@@ -116,7 +117,7 @@ function solve_poisson_lowlevel(FES_time, FES_space, μ, f)
116117
ExtendableSparse.flush!(A)
117118
end
118119

119-
@info ".... spy plot of system matrix:\n$(UnicodePlots.spy(sparse(A.cscmatrix)))"
120+
@info ".... spy plot of system matrix:\n$(UnicodePlots.spy(A.cscmatrix))"
120121

121122
## solve
122123
println("Solving linear system...")

examples/Example210_LowLevelNavierStokes.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ using ExtendableFEMBase
3535
using ExtendableGrids
3636
using ExtendableSparse
3737
using GridVisualize
38+
using UnicodePlots, Term
3839
using ForwardDiff
3940
using DiffResults
4041

@@ -63,7 +64,7 @@ function p!(pval, qpinfo)
6364
return nothing
6465
end
6566

66-
function main(; nref = 5, teval = 0, order = 2, Plotter = nothing)
67+
function main(; nref = 5, teval = 0, order = 2, Plotter = UnicodePlots)
6768

6869
@assert order >= 2
6970

@@ -98,9 +99,11 @@ function main(; nref = 5, teval = 0, order = 2, Plotter = nothing)
9899
println("l2 error pressure = $(error_p)")
99100

100101
## plot
101-
plt = GridVisualizer(; Plotter = Plotter, layout = (1, 1), clear = true, resolution = (500, 500))
102-
scalarplot!(plt[1, 1], xgrid, nodevalues(sol[1]; abs = true)[1, :]; title = "|u| + quiver", Plotter = Plotter)
103-
vectorplot!(plt[1, 1], xgrid, eval_func_bary(PointEvaluator([(1, Identity)], sol)), clear = false)
102+
plt = GridVisualizer(; Plotter = Plotter, layout = (1, 2), clear = true, resolution = (1200, 600))
103+
scalarplot!(plt[1, 1], sol[1]; title = "|u| + quiver", abs = true)
104+
vectorplot!(plt[1, 1], sol[1]; clear = false)
105+
scalarplot!(plt[1, 2], sol[2]; title = "p")
106+
reveal(plt)
104107

105108
return sol, plt
106109
end

examples/Example280_BasisPlotter.jl

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,23 @@
66
This example plots all the basis functions of a H1 finite element on Edge1D or Triangle2D
77
as unicode plots. This is the result with the default parameters (dim = 1, order = 3):
88
9-
![](https://github.com/chmerdon/ExtendableFEMBase.jl/blob/master/docs/src/assets/example280.png?raw=true")
9+
![](example280.png)
1010
1111
=#
1212

1313
module Example280_BasisPlotter
1414

1515
using ExtendableFEMBase
1616
using ExtendableGrids
17+
using GridVisualize
18+
using UnicodePlots, Term
1719

1820
## everything is wrapped in a main function
19-
function main(; dim = 1, order = 3)
21+
function main(; dim = 1, order = 3, Plotter = UnicodePlots)
2022

2123
## generate two grids
2224
@assert dim in [1, 2] "dim must be 1 or 2"
25+
@assert order in 1:4 "order must be between 1 and 4"
2326
refgeom = dim == 1 ? Edge1D : Triangle2D
2427
xgrid = reference_domain(refgeom)
2528

@@ -36,7 +39,41 @@ function main(; dim = 1, order = 3)
3639
FEFunc[1][j + coffsets[j]] = 1
3740
end
3841

42+
## interpolate on finer grid
43+
xgrid_plot = dim == 1 ? simplexgrid(0:0.01:1) : uniform_refine(xgrid, 4)
44+
I = FEVector(FESpace{H1P1{ndofs}}(xgrid_plot))
45+
lazy_interpolate!(I[1], FEFunc, [(1, Identity)])
46+
3947
## plot
40-
return println(stdout, unicode_scalarplot(FEFunc[1]; title = "φ", ylim = (-0.5, 1), resolution = dim == 1 ? (40, 10) : (20, 15), nrows = order))
48+
if dim == 1
49+
layout = (1, 1) # everything is plotted into one plot
50+
size = (600, 600)
51+
colors = [:red, :green, :blue, :white, :yellow, :cyan, :magenta]
52+
elseif dim == 2
53+
l = round(Int, ceil(sqrt(ndofs)))
54+
if l^2 - l >= ndofs
55+
layout = (l - 1, l)
56+
else
57+
layout = (l, l)
58+
end
59+
size = (1000, 1000)
60+
p = permutedims(reshape(1:prod(layout), layout))[:]
61+
end
62+
plt = GridVisualizer(; Plotter = Plotter, layout = layout, size = size)
63+
for j in 1:ndofs
64+
if dim == 1
65+
ExtendableFEMBase.scalarplot!(plt[1], I[1], IdentityComponent{j}; Plotter = Plotter, clear = false, title = "dof $j", color = dim == 1 ? colors[j] : :white)
66+
else
67+
ExtendableFEMBase.scalarplot!(plt[p[j]], I[1], IdentityComponent{j}; Plotter = Plotter, clear = false, title = "dof $j", color = dim == 1 ? colors[j] : :white)
68+
end
69+
end
70+
reveal(plt)
71+
return FEFunc, plt
72+
end
73+
74+
function generateplots(dir = pwd(); Plotter = nothing, kwargs...)
75+
~, plt = main(; Plotter = Plotter, kwargs...)
76+
scene = GridVisualize.reveal(plt)
77+
return GridVisualize.save(joinpath(dir, "example280.png"), scene; Plotter = Plotter)
4178
end
4279
end

examples/Example281_DiscontinuousPlot.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module Example281_DiscontinuousPlot
1616
using ExtendableFEMBase
1717
using ExtendableGrids
1818
using GridVisualize
19+
using UnicodePlots, Term
1920

2021
## function to interpolate
2122
function u!(result, qpinfo)
@@ -30,7 +31,7 @@ function u!(result, qpinfo)
3031
end
3132

3233
## everything is wrapped in a main function
33-
function main(; broken = false, nrefs = 3, abs = false, Plotter = nothing)
34+
function main(; broken = false, nrefs = 3, abs = false, Plotter = UnicodePlots)
3435

3536
## generate two grids
3637
xgrid = grid_unitsquare(Triangle2D)
@@ -61,13 +62,14 @@ function main(; broken = false, nrefs = 3, abs = false, Plotter = nothing)
6162
nodevals4nodes2 = nodevalues(FEFunction[1], Identity; abs = abs, regions = [2], nodes = subnodes2)
6263

6364
## plot
64-
if Plotter !== nothing
65-
p = GridVisualizer(; Plotter = Plotter, layout = (2, 2), clear = true, resolution = (1000, 500))
66-
gridplot!(p[1, 1], xgrid)
67-
scalarplot!(p[1, 2], [subgrid1, subgrid2], xgrid, [view(nodevals4nodes1, :), view(nodevals4nodes2, :)], cellwise = false, levels = 11, title = "u")
68-
end
69-
70-
return p
65+
plt = GridVisualizer(; Plotter = Plotter, layout = (1, 5), clear = true, resolution = (1500, 300))
66+
gridplot!(plt[1, 1], xgrid)
67+
scalarplot!(plt[1, 2], subgrid1, view(nodevals4nodes1, :), cellwise = false, levels = 11, title = "u (region 1)")
68+
scalarplot!(plt[1, 3], subgrid2, view(nodevals4nodes2, :), cellwise = false, levels = 11, title = "u (region 2)")
69+
scalarplot!(plt[1, 4], [subgrid1, subgrid2], xgrid, [view(nodevals4nodes1, :), view(nodevals4nodes2, :)], cellwise = false, levels = 11, title = "u")
70+
broken_scalarplot!(plt[1, 5], FEFunction[1])
71+
reveal(plt)
72+
return plt
7173
end
7274

7375
function generateplots(dir = pwd(); Plotter = nothing, kwargs...)

examples/Example290_InterpolationBetweenMeshes.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module Example290_InterpolationBetweenMeshes
1616
using ExtendableFEMBase
1717
using ExtendableGrids
1818
using GridVisualize
19+
using UnicodePlots, Term
1920

2021
## function to interpolate
2122
function u!(result, qpinfo)
@@ -25,7 +26,7 @@ function u!(result, qpinfo)
2526
end
2627

2728
## everything is wrapped in a main function
28-
function main(; ν = 1.0e-3, nrefs = 4, Plotter = nothing)
29+
function main(; ν = 1.0e-3, nrefs = 3, Plotter = UnicodePlots)
2930

3031
## generate two grids
3132
xgrid1 = uniform_refine(grid_unitsquare(Triangle2D), nrefs)
@@ -52,11 +53,13 @@ function main(; ν = 1.0e-3, nrefs = 4, Plotter = nothing)
5253
@time lazy_interpolate!(FEFunction2[1], FEFunction1; use_cellparents = true)
5354

5455
## plot
55-
p = GridVisualizer(; Plotter = Plotter, layout = (1, 2), clear = true, resolution = (800, 400))
56-
scalarplot!(p[1, 1], xgrid1, view(nodevalues(FEFunction1[1]), 1, :), levels = 11, title = "u_h ($FEType1, coarse grid)")
57-
scalarplot!(p[1, 2], xgrid2, view(nodevalues(FEFunction2[1]), 1, :), levels = 11, title = "u_h ($FEType2, fine grid)")
58-
59-
return p
56+
plt = GridVisualizer(; Plotter = Plotter, layout = (2, 2), clear = true, resolution = (1000, 1000))
57+
scalarplot!(plt[1, 1], FEFunction1[1], levels = 11, title = "u_h ($FEType1, coarse grid)")
58+
scalarplot!(plt[1, 2], FEFunction2[1], levels = 11, title = "u_h ($FEType2, fine grid)")
59+
gridplot!(plt[2, 1], xgrid1, title = "coarse grid", markersize = 0)
60+
gridplot!(plt[2, 2], xgrid2, title = "fine grid", markersize = 0)
61+
reveal(plt)
62+
return plt
6063
end
6164

6265
function generateplots(dir = pwd(); Plotter = nothing, kwargs...)

ext/ExtendableFEMBaseUnicodePlotsExt.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ function unicode_gridplot(
1818
plot_based = ON_CELLS, # or ON_FACES/ON_EDGES
1919
kwargs...,
2020
)
21+
Base.depwarn(
22+
"The unicode extension of ExtendableFEMBase will be deprecated in a future release. A unicode gridplot can now be achieved
23+
via GridVisualize and UnicodePlots as an backend, e.g., use gridplot(xgrid; Plotter = UnicodePlots) instead of unicode_gridplot(xgrid)",
24+
:unicode_gridplot; force = true
25+
)
2126
coords = xgrid[Coordinates]
2227
ex = extrema(view(coords, 1, :))
2328
ey = extrema(view(coords, 2, :))
@@ -85,6 +90,12 @@ function unicode_scalarplot(
8590
title = u.name,
8691
kwargs...
8792
)
93+
Base.depwarn(
94+
"The unicode extension of ExtendableFEMBase will be deprecated in a future release. A unicode scalarplot can now be achieved
95+
via GridVisualize and UnicodePlots as an backend, e.g., use scalarplot(u; Plotter = UnicodePlots)
96+
instead of unicode_scalarplot(u)",
97+
:unicode_scalarplot; force = true
98+
)
8899

89100
xgrid = u.FES.xgrid
90101
coords = xgrid[Coordinates]

0 commit comments

Comments
 (0)