Skip to content

Commit 47cbdcd

Browse files
joa-quimclaude
andauthored
kwargs protection: plotting modules (#1919)
Split entry points from main logic in plotting module wrappers so that kwargs are converted to Dict{Symbol,Any} via init_module in thin wrappers before calling the main function. This prevents Julia recompilation when kwargs change. Affected modules: plot (fill_between, helper_hvband, ternary), pslegend, psmask, psrose, pssolar, pswiggle, gmtlogo, windbarbs, psvelo, psmeca/coupe, gmtisf. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2734604 commit 47cbdcd

11 files changed

Lines changed: 114 additions & 91 deletions

File tree

src/geodesy/psvelo.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ See full GMT docs at [`velo`]($(GMTdoc)supplements/seis/velo.html)
99
velo(mat2ds([0. -8 0 0 4 6 0.5; -8 5 3 3 0 0 0.5], ["4x6", "3x3"]), pen=(0.6,:red), fill_wedges=:green, outlines=true, Se="0.2/0.39/18", arrow="0.3c+p1p+e+gred", region=(-15,10,-10,10), show=1)
1010
```
1111
"""
12-
function velo(cmd0::String="", arg1=nothing; first=true, kwargs...)
12+
velo!(cmd0::String="", arg1=nothing; kw...) = velo(cmd0, arg1; first=false, kw...)
13+
velo(arg1; kw...) = velo("", arg1; first=true, kw...)
14+
velo!(arg1; kw...) = velo("", arg1; first=false, kw...)
15+
function velo(cmd0::String="", arg1=nothing; first=true, kw...)
16+
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
17+
velo(cmd0, arg1, O, K, d)
18+
end
19+
function velo(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
1320

1421
proggy = (IamModern[]) ? "velo " : "psvelo "
1522

16-
d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode
17-
1823
cmd, _, _, opt_R = parse_BJR(d, "", "", O, " -JX15cd/0d")
19-
cmd, = parse_common_opts(d, cmd, [:UVXY :di :e :p :t :params]; first=first)
24+
cmd, = parse_common_opts(d, cmd, [:UVXY :di :e :p :t :params]; first=!O)
2025

2126
if ((val = find_in_dict(d, [:A :arrow :arrows])[1]) !== nothing)
2227
cmd = (isa(val, String)) ? cmd * " -A" * val : cmd * " -A" * vector_attrib(val)
@@ -44,10 +49,5 @@ function velo(cmd0::String="", arg1=nothing; first=true, kwargs...)
4449
prep_and_call_finish_PS_module(d, cmd, "", K, O, true, arg1)
4550
end
4651

47-
# ---------------------------------------------------------------------------------------------------
48-
velo!(cmd0::String="", arg1=nothing; kw...) = velo(cmd0, arg1; first=false, kw...)
49-
velo(arg1; kw...) = velo("", arg1; first=true, kw...)
50-
velo!(arg1; kw...) = velo("", arg1; first=false, kw...)
51-
5252
const psvelo = velo # Alias
5353
const psvelo! = velo! # Alias

src/gmtlogo.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,16 @@ Parameters
3434
3535
- Example, make a GMT Julia logo with circles of 1 cm: logo(GMTjulia=1, show=true)
3636
"""
37-
function logo(cmd0::String=""; first=true, kwargs...)
38-
39-
d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode
37+
logo!(cmd0::String=""; first=false, kw...) = logo(cmd0; first=first, kw...)
38+
function logo(cmd0::String=""; first=true, kw...)
39+
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
40+
logo(cmd0, O, K, d)
41+
end
42+
function logo(cmd0::String, O::Bool, K::Bool, d::Dict{Symbol, Any})
4043

4144
cmd, = parse_R(d, "", O=O)
4245
cmd, = parse_J(d, cmd, default=" -Jx1", map=true, O=O)
43-
cmd, = parse_common_opts(d, cmd, [:UVXY :params]; first=first)
46+
cmd, = parse_common_opts(d, cmd, [:UVXY :params]; first=!O)
4447

4548
cmd = parse_type_anchor(d, cmd, [:D :pos :position],
4649
(map=("g", arg2str, 1), outside=("J", nothing, 1), inside=("j", nothing, 1), norm=("n", arg2str, 1), paper=("x", arg2str, 1), anchor=("", arg2str, 2), width="+w", size="+w", justify="+j", offset=("+o", arg2str)), 'g')
@@ -78,9 +81,6 @@ function logo(cmd0::String=""; first=true, kwargs...)
7881
end
7982
end
8083

81-
# ---------------------------------------------------------------------------------------------------
82-
logo!(cmd0::String=""; first=false, kw...) = logo(cmd0; first=first, kw...)
83-
8484
# -------------------------------------------------------------------------
8585
function jlogo(L::Float64=5.0)
8686
# Create the Julia "Terminator" 3 colored circles triangle
@@ -97,4 +97,4 @@ function jlogo(L::Float64=5.0)
9797
end
9898

9999
const gmtlogo = logo # Alias
100-
const gmtlogo! = logo!
100+
const gmtlogo! = logo!

src/plot.jl

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,12 @@ Example:
693693
fill_between([theta y1], [theta y2], white=true, legend="Sinc1,Sinc2", show=1)
694694
"""
695695
fill_between(fname::String; first::Bool=true, kw...) = fill_between(gmtread(fname); first=first, kw...)
696-
function fill_between(arg1, arg2=nothing; first=true, kwargs...)
696+
fill_between!(arg1, arg2=nothing; kw...) = fill_between(arg1, arg2; first=false, kw...)
697+
function fill_between(arg1, arg2=nothing; first=true, kw...)
698+
d = init_module(false, kw...)[1]
699+
fill_between(arg1, arg2, first, d)
700+
end
701+
function fill_between(arg1, arg2, first::Bool, d::Dict{Symbol, Any})
697702

698703
function find_the_pos(x, x_int)
699704
len_x = length(x)
@@ -714,7 +719,6 @@ function fill_between(arg1, arg2=nothing; first=true, kwargs...)
714719
return legs
715720
end
716721

717-
d = init_module(false, kwargs...)[1] # Also checks if the user wants ONLY the HELP mode
718722
fc = helper_ds_fill(d) # Got fill colors?
719723
if (!isempty(fc))
720724
!any(contains.(fc, "@")) && (fc .*= "@60") # If no transparency provided default to 60%
@@ -863,8 +867,6 @@ function fill_between(arg1, arg2=nothing; first=true, kwargs...)
863867
=#
864868
end
865869

866-
fill_between!(arg1, arg2=nothing; kw...) = fill_between(arg1, arg2; first=false, kw...)
867-
868870
# ------------------------------------------------------------------------------------------------------
869871
"""
870872
stairs(cmd0::String="", arg1=nothing; step=:post, kwargs...)
@@ -1532,9 +1534,12 @@ const vspan! = vband!
15321534
const hspan = hband
15331535
const hspan! = hband!
15341536

1535-
function helper_hvband(mat::Matrix{<:Real}, tipo="v"; width=false, height=false, percent=false, first=true, kwargs...)
1537+
function helper_hvband(mat::Matrix{<:Real}, tipo="v"; width=false, height=false, percent=false, first=true, kw...)
1538+
d, _, O = init_module(first, kw...)
1539+
helper_hvband(mat, tipo, width, height, percent, O, d)
1540+
end
1541+
function helper_hvband(mat::Matrix{<:Real}, tipo, width, height, percent, O::Bool, d::Dict{Symbol, Any})
15361542
# This is the main function for the hband and vband functions.
1537-
d, _, O = init_module(first, kwargs...)
15381543
cmd, = parse_R(d, "", O=O, del=false)
15391544
all(CTRL.limits .== 0.) && error("Need to know the axes limits in a numeric form.")
15401545
cmd, = parse_J(d, cmd, default="", map=true, O=O, del=false)
@@ -1576,7 +1581,7 @@ function helper_hvband(mat::Matrix{<:Real}, tipo="v"; width=false, height=false,
15761581

15771582
d[:S] = bB # Add -Sb|B, otherwise headers are not scanned.
15781583
got_pattern && (d[:G] = "p1") # Patterns fck the session. Use this to inform gmt() that session must be recreated
1579-
common_plot_xyz("", D, "", first, false, d)
1584+
common_plot_xyz("", D, "", !O, false, d)
15801585
end
15811586

15821587
# ------------------------------------------------------------------------------------------------------
@@ -1668,11 +1673,17 @@ Other than the above options, the `kwargs` input accepts still the following opt
16681673
- `clockwise`: - Set it to `true` to indicate that positive axes directions be clock-wise
16691674
[Default lets the a, b, c axes be positive in a counter-clockwise direction].
16701675
"""
1671-
function ternary(cmd0::String="", arg1=nothing; first::Bool=true, image::Bool=false, kwargs...)
1672-
# A wrapper for psternary
1676+
ternary!(cmd0::String="", arg1=nothing; kw...) = ternary(cmd0, arg1; first=false, kw...)
1677+
ternary(arg1; kw...) = ternary("", arg1; first=true, kw...)
1678+
ternary!(arg1; kw...) = ternary("", arg1; first=false, kw...)
1679+
function ternary(cmd0::String="", arg1=nothing; first::Bool=true, image::Bool=false, kw...)
16731680
(cmd0 == "" && arg1 === nothing) && (arg1 = [0.0 0.0 0.0]) # No data in, just a kind of ternary basemap
16741681
(cmd0 != "") && (arg1 = gmtread(cmd0))
1675-
d = init_module(first, kwargs...)[1]
1682+
d = init_module(first, kw...)[1]
1683+
ternary(arg1, first, image, d)
1684+
end
1685+
function ternary(arg1, first::Bool, image::Bool, d::Dict{Symbol, Any})
1686+
# A wrapper for psternary
16761687
opt_J::String = parse_J(d, "", default=" -JX" * split(DEF_FIG_SIZE, '/')[1] * "/0", map=true, O=false, del=false)[2]
16771688
opt_R::String = parse_R(d, "")[1]
16781689
d[:R] = (opt_R == "") ? "0/100/0/100/0/100" : opt_R[4:end]
@@ -1768,10 +1779,6 @@ function dict_auto_add!(d::Dict)
17681779
end
17691780
end
17701781

1771-
ternary!(cmd0::String="", arg1=nothing; kw...) = ternary(cmd0, arg1; first=false, kw...)
1772-
ternary(arg1; kw...) = ternary("", arg1; first=true, kw...)
1773-
ternary!(arg1; kw...) = ternary("", arg1; first=false, kw...)
1774-
ternary(kw...) = ternary("", nothing; first=true, kw...)
17751782
const psternary = ternary # Aliases
17761783
const psternary! = ternary! # Aliases
17771784

src/pslegend.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,19 @@ Parameters
4242
4343
To see the full documentation type: ``@? legend``
4444
"""
45-
function legend(cmd0::String="", arg1=nothing; first::Bool=true, kwargs...)
45+
legend!(cmd0::String="", arg1=nothing; kw...) = legend(cmd0, arg1; first=false, kw...)
46+
legend(arg1; kw...) = legend("", arg1; first=true, kw...)
47+
legend!(arg1; kw...) = legend("", arg1; first=false, kw...)
48+
function legend(cmd0::String="", arg1=nothing; first::Bool=true, kw...)
49+
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
50+
legend(cmd0, arg1, O, K, d)
51+
end
52+
function legend(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
4653

4754
gmt_proggy = (IamModern[]) ? "legend " : "pslegend "
4855

49-
d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode
50-
5156
if (cmd0 == "" && arg1 === nothing && !IamModern[])
52-
first && error("Need input data or file for legend")
57+
!O && error("Need input data or file for legend")
5358
# Here we have a bit of a convoluted case. This section is for the case where 'legend' is called without
5459
# input data and relies on the data stored in previous commands by using the 'legend' keyword. That is,
5560
# we use the keyword option 'position', 'fontsize', etc args as kwargs to 'legend'. As said, convoluted.
@@ -79,7 +84,7 @@ function legend(cmd0::String="", arg1=nothing; first::Bool=true, kwargs...)
7984
# where the default is 8 pts. This allows for the user to set options 'fontsize' or 'font' to override the defaults.
8085
((fnt = get_legend_font(d, IamModern[] ? 0 : 8; modern=IamModern[])) != "") && (cmd *= " --FONT_ANNOT_PRIMARY=" * fnt)
8186

82-
cmd, = parse_common_opts(d, cmd, [:F :c :p :q :t :JZ :UVXY :params]; first=first)
87+
cmd, = parse_common_opts(d, cmd, [:F :c :p :q :t :JZ :UVXY :params]; first=!O)
8388

8489
opt_D = parse_type_anchor(d, "", [:D :pos :position],
8590
(map=("g", arg2str, 1), outside=("J", arg2str, 1), inside=("j", arg2str, 1), norm=("n", arg2str, 1), paper=("x", arg2str, 1), anchor=("", arg2str, 2), width=("+w", arg2str), justify="+j", spacing="+l", offset=("+o", arg2str)), 'j')
@@ -244,10 +249,5 @@ function mk_legend(; kwargs...)
244249
leg
245250
end
246251

247-
# ---------------------------------------------------------------------------------------------------
248-
legend!(cmd0::String="", arg1=nothing; kw...) = legend(cmd0, arg1; first=false, kw...)
249-
legend(arg1; kw...) = legend("", arg1; first=true, kw...)
250-
legend!(arg1; kw...) = legend("", arg1; first=false, kw...)
251-
252252
const pslegend = legend # Alias
253253
const pslegend! = legend! # Alias

src/psmask.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,19 @@ Parameters
6060
6161
To see the full documentation type: ``@? mask``
6262
"""
63-
function mask(cmd0::String="", arg1=nothing; first=true, kwargs...)
63+
mask!(cmd0::String="", arg1=nothing; kw...) = mask(cmd0, arg1; first=false, kw...)
64+
mask(arg1; kw...) = mask("", arg1; first=true, kw...)
65+
mask!(arg1; kw...) = mask("", arg1; first=false, kw...)
66+
function mask(cmd0::String="", arg1=nothing; first=true, kw...)
67+
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
68+
mask(cmd0, arg1, O, K, d)
69+
end
70+
function mask(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
6471

6572
gmt_proggy = (IamModern[]) ? "mask " : "psmask "
6673

67-
d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode
68-
6974
cmd, _, _, opt_R = parse_BJR(d, "", "", O, " -JX15c/15c")
70-
cmd, = parse_common_opts(d, cmd, [:I :UVXY :JZ :c :e :p :r :t :w :params]; first=first)
75+
cmd, = parse_common_opts(d, cmd, [:I :UVXY :JZ :c :e :p :r :t :w :params]; first=!O)
7176
cmd = parse_these_opts(cmd, d, [[:C :endclip :end_clip_path], [:D :dump], [:L :nodegrid], [:N :invert :inverse],
7277
[:Q :cut :cut_number], [:S :search_radius], [:T :tiles]])
7378

@@ -92,11 +97,6 @@ function mask(cmd0::String="", arg1=nothing; first=true, kwargs...)
9297
prep_and_call_finish_PS_module(d, cmd, "", K, O, true, arg1)
9398
end
9499

95-
# ---------------------------------------------------------------------------------------------------
96-
mask!(cmd0::String="", arg1=nothing; kw...) = mask(cmd0, arg1; first=false, kw...)
97-
mask(arg1; kw...) = mask("", arg1; first=true, kw...)
98-
mask!(arg1; kw...) = mask("", arg1; first=false, kw...)
99-
100100
# ---------------------------------------------------------------------------------------------------
101101
# This method has nothing to do with psmask, but can be seen as an extension to it.
102102
function mask(GI::GItype, D::GDtype; touches=false, inverse::Bool=false)

src/psrose.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,23 @@ Parameters
7272
7373
To see the full documentation type: ``@? rose``
7474
"""
75-
rose(cmd0::String; kwargs...) = rose_helper(cmd0, nothing; kwargs...)
76-
rose(arg1; kwargs...) = rose_helper("", arg1; kwargs...)
77-
rose!(cmd0::String; kwargs...) = rose_helper(cmd0, nothing; first=false, kwargs...)
78-
rose!(arg1; kwargs...) = rose_helper("", arg1; first=false, kwargs...)
75+
rose(cmd0::String; kw...) = rose_helper(cmd0, nothing; kw...)
76+
rose(arg1; kw...) = rose_helper("", arg1; kw...)
77+
rose!(cmd0::String; kw...) = rose_helper(cmd0, nothing; first=false, kw...)
78+
rose!(arg1; kw...) = rose_helper("", arg1; first=false, kw...)
7979

8080
# ---------------------------------------------------------------------------------------------------
81-
function rose_helper(cmd0::String, arg1; first=true, kwargs...)
81+
function rose_helper(cmd0::String, arg1; first=true, kw...)
82+
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
83+
rose_helper(cmd0, arg1, O, K, d)
84+
end
85+
function rose_helper(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
8286

8387
gmt_proggy = (IamModern[]) ? "rose " : "psrose "
8488

8589
arg2 = nothing # May be needed if GMTcpt type is sent in via C
8690
N_args = (arg1 === nothing) ? 0 : 1
8791

88-
d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode
89-
9092
# If inquire, no plotting so do it and return
9193
cmd = add_opt(d, "", "I", [:I :inquire])
9294
if (cmd != "")
@@ -96,7 +98,7 @@ function rose_helper(cmd0::String, arg1; first=true, kwargs...)
9698
end
9799

98100
cmd, opt_B, opt_J, opt_R = parse_BJR(d, "", "", O, " -JX15c")
99-
cmd, = parse_common_opts(d, cmd, [:UVXY :c :e :p :t :w :margin :params]; first=first)
101+
cmd, = parse_common_opts(d, cmd, [:UVXY :c :e :p :t :w :margin :params]; first=!O)
100102
cmd = parse_these_opts(cmd, d, [[:D :shift], [:F :no_scale], [:L :labels], [:M :vector_params], [:N :vonmises],
101103
[:Q :alpha], [:S :norm :normalize], [:T :orientation], [:Z :scale]])
102104
cmd = add_opt(d, cmd, "A", [:A :sector :sectors], (width="", rose="_+r"))

src/pssolar.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,19 @@ Parameters
3939
4040
To see the full documentation type: ``@? solar``
4141
"""
42-
function solar(cmd0::String="", arg1=nothing; first=true, kwargs...)
42+
solar!(cmd0::String="", arg1=nothing; kw...) = solar(cmd0, arg1; first=false, kw...)
43+
function solar(cmd0::String="", arg1=nothing; first=true, kw...)
44+
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
45+
solar(cmd0, arg1, O, K, d)
46+
end
47+
function solar(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
4348

4449
gmt_proggy = (IamModern[]) ? "solar " : "pssolar "
45-
d, K, O = init_module(first, kwargs...) # Also checks if the user wants ONLY the HELP mode
4650

4751
def_J = (isempty(d)) ? " -JG0/0/14c" : " -JX14cd/0d"
4852
(isempty(d)) && (d[:coast] = true; d[:T] = :d; d[:G] = "navy@75"; d[:show] = true)
4953
cmd, _, opt_J, = parse_BJR(d, "", "", O, def_J)
50-
cmd, = parse_common_opts(d, cmd, [:bo :c :h :o :p :t :UVXY :params]; first=first)
54+
cmd, = parse_common_opts(d, cmd, [:bo :c :h :o :p :t :UVXY :params]; first=!O)
5155
cmd = parse_these_opts(cmd, d, [[:C :format], [:M :dump], [:N :invert]])
5256

5357
cmd = add_opt_fill(cmd, d, [:G :fill], 'G')
@@ -69,7 +73,5 @@ function solar(cmd0::String="", arg1=nothing; first=true, kwargs...)
6973
end
7074

7175
# ---------------------------------------------------------------------------------------------------
72-
solar!(cmd0::String="", arg1=nothing; kw...) = solar(cmd0, arg1; first=false, kw...)
73-
7476
const pssolar = solar # Alias
75-
const pssolar! = solar! # Alias
77+
const pssolar! = solar! # Alias

src/pswiggle.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,14 @@ const pswiggle! = wiggle! # Alias
6565

6666
# ---------------------------------------------------------------------------------------------------
6767
function wiggle_helper(cmd0::String, arg1; first=true, kw...)
68-
gmt_proggy = (IamModern[]) ? "wiggle " : "pswiggle "
69-
7068
d, K, O = init_module(first, kw...) # Also checks if the user wants ONLY the HELP mode
69+
wiggle_helper(cmd0, arg1, O, K, d)
70+
end
71+
function wiggle_helper(cmd0::String, arg1, O::Bool, K::Bool, d::Dict{Symbol, Any})
72+
gmt_proggy = (IamModern[]) ? "wiggle " : "pswiggle "
7173

7274
cmd, opt_B, opt_J, opt_R = parse_BJR(d, "", "", O, " -JX15c/0")
73-
cmd, = parse_common_opts(d, cmd, [:c :e :f :g :p :t :w :F :UVXY :margin :params]; first=first)
75+
cmd, = parse_common_opts(d, cmd, [:c :e :f :g :p :t :w :F :UVXY :margin :params]; first=!O)
7476
cmd = parse_these_opts(cmd, d, [[:A :azimuth], [:C :center], [:I :fixed_azim], [:S], [:Z :ampscale :amp_scale]])
7577

7678
# If file name sent in, read it and compute a tight -R if this was not provided

src/seis/gmtisf.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ Parameters
2727
2828
This module can also be called via `gmtread`. _I.,e._ `gmtread("file.isf", opts...)_
2929
"""
30-
function gmtisf(cmd0::String; kwargs...)::GMTdataset{Float64,2}
31-
32-
d = init_module(false, kwargs...)[1] # Also checks if the user wants ONLY the HELP mode
30+
function gmtisf(cmd0::String; kw...)::GMTdataset{Float64,2}
31+
d = init_module(false, kw...)[1]
32+
gmtisf(cmd0, d)
33+
end
34+
function gmtisf(cmd0::String, d::Dict{Symbol, Any})::GMTdataset{Float64,2}
3335

3436
cmd = parse_common_opts(d, "", [:R :V_params :yx])[1]
3537
cmd = parse_these_opts(cmd, d, [[:F :focal], [:D :date], [:N :notime]])

0 commit comments

Comments
 (0)