Skip to content

Commit b3175b6

Browse files
authored
Replace several find_in_dict by hlp_desany. (#1788)
Rework plt_txt_attrib()
1 parent 22397fa commit b3175b6

2 files changed

Lines changed: 66 additions & 45 deletions

File tree

src/psxy.jl

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool,
3535
cmd, is_gridtri, arg1 = parse_grid2tri_case(d, cmd, caller, is3D, isFV, O, arg1)
3636

3737
isa(arg1, GMTdataset) && (arg1 = with_xyvar(d, arg1)) # See if we have a column request based on column names
38-
if ((val = find_in_dict(d, [:decimate])[1]) !== nothing) # Asked for a clever data decimation?
38+
if ((val = hlp_desnany_int(d, [:decimate])) !== -999) # Asked for a clever data decimation?
3939
dec_factor::Int = (val == 1) ? 10 : val
4040
arg1 = lttb(arg1, dec_factor)
4141
end
@@ -176,8 +176,7 @@ function _common_plot_xyz(cmd0::String, arg1, caller::String, O::Bool, K::Bool,
176176
end
177177

178178
opt_Wmarker::String = ""
179-
if ((val = find_in_dict(d, [:mec :markeredgecolor :MarkerEdgeColor])[1]) !== nothing)
180-
tmec::String = arg2str(val)
179+
if ((tmec = hlp_desnany_arg2str(d, [:mec :markeredgecolor :MarkerEdgeColor])) !== "")
181180
!contains(tmec, "p,") && (tmec = "0.25p," * tmec) # If not provided, default to a line thickness of 0.25p
182181
opt_Wmarker = tmec
183182
end
@@ -377,7 +376,7 @@ end
377376
function parse_plot_callers(d::Dict{Symbol, Any}, gmt_proggy::String, caller::String, is3D::Bool, O::Bool, arg1)
378377
isFV = (isa(arg1, GMTfv) || isa(arg1, Vector{GMTfv}))
379378
(arg1 !== nothing && !isa(arg1, GDtype) && !isa(arg1, Matrix{<:Real}) && !isFV) &&
380-
(arg1 = tabletypes2ds(arg1, ((val = find_in_dict(d, [:interp])[1]) !== nothing) ? interp=val : interp=0))
379+
(arg1 = tabletypes2ds(arg1, ((val = hlp_desnany_int(d, [:interp])) !== -999) ? interp=val : interp=0))
381380
(caller != "bar") && (arg1 = if_multicols(d, arg1, is3D)) # Repeat because DataFrames or ODE's have skipped first round
382381
(!O) && (LEGEND_TYPE[1] = legend_bag()) # Make sure that we always start with an empty one
383382

@@ -400,7 +399,7 @@ function parse_plot_callers(d::Dict{Symbol, Any}, gmt_proggy::String, caller::St
400399
sub_module = caller
401400
# Needs to be processed here to distinguish from the more general 'fill'
402401
(caller == "bar") && (g_bar_fill = helper_gbar_fill(d))
403-
opt_A = (caller == "lines" && ((val = find_in_dict(d, [:stairs_step])[1]) !== nothing)) ? string(val) : ""
402+
opt_A = (caller == "lines" && ((val = hlp_desnany_str(d, [:stairs_step])) !== "")) ? val : ""
404403
end
405404
end
406405
return cmd, isFV, caller, sub_module, gmt_proggy, opt_A, g_bar_fill, arg1
@@ -410,32 +409,43 @@ end
410409
plt_txt_attrib!(D::GMTdataset{T,N}, d::Dict{Symbol, Any}, _cmd::Vector{String}) where {T,N} = plt_txt_attrib!([D], d, _cmd)
411410
function plt_txt_attrib!(D::Vector{<:GMTdataset{T,N}}, d::Dict{Symbol, Any}, _cmd::Vector{String}) where {T,N}
412411
# Plot TEXT attributed labels and serve as function barrier agains the f Any's (not sure if succeeds)
413-
((val = find_in_dict(d, [:labels])[1]) === nothing) && return nothing
414-
415-
s_val::String = string(val)
416-
!(startswith(s_val, "att") && (contains(s_val, '=') || contains(s_val, ':'))) &&
417-
error("The labels option must be 'labels=att=???' or 'labels=attrib=???'")
418-
((_ind = findfirst('=', s_val)) === nothing) && (_ind = findfirst(':', s_val))
419-
ind::Int = _ind # Because it fck insists _ind is a Any
420-
ts::String = s_val[ind+1:end]
421-
t = vec(make_attrtbl(D, att=ts)[1])
422-
if ((fnt = add_opt(d, "", "", [:font], (angle="+a", font=("+f", font)); del=false)) != "")
412+
((s_val = hlp_desnany_str(d, [:labels])) === "") && return nothing
413+
414+
if ((fnt = add_opt(d, "", "", [:font], (angle="+a", font=("+f", font)); del=false)) !== "")
423415
(fnt[1] != '+') && (fnt = "+f" * fnt)
424416
delete!(d, :font)
417+
end
418+
419+
if (length(D) == 1 && D[1].geom == wkbPoint) # Points only. Expected to have a text column
420+
(CTRL.pocket_call[1] === nothing) ? (CTRL.pocket_call[1] = D[1]) : (CTRL.pocket_call[2] = D[1])
421+
(fnt === "") && (fnt = "+f6p")
425422
else
426-
nc::Int = round(Int, sqrt(length(D))) # A crude guess of the number of columns
427-
fnt = (nc < 5) ? "7p" : (nc < 9 ? "5p" : "4p") # A simple heuristic
428-
outline = fnt * ",black=~0.75p,white " # Apply the outline trick
429-
fnt = "+f"
430-
t = outline .* t
431-
end
432-
ct::GMTdataset{Float64,2} = mat2ds(gmt_centroid_area(G_API[1], D, Int(isgeog(D))))
433-
ct.text = t # Texts will be plotted at the polygons centroids
434-
(CTRL.pocket_call[1] === nothing) ? (CTRL.pocket_call[1] = ct) : (CTRL.pocket_call[2] = ct)
423+
ts = fish_attrib_in_str(s_val)
424+
t = vec(make_attrtbl(D, att=ts)[1])
425+
if (fnt === "")
426+
nc::Int = round(Int, sqrt(length(D))) # A crude guess of the number of columns
427+
fnt = (nc < 5) ? "7p" : (nc < 9 ? "5p" : "4p") # A simple heuristic
428+
outline = fnt * ",black=~0.75p,white " # Apply the outline trick
429+
fnt = "+f"
430+
t = outline .* t
431+
end
432+
ct::GMTdataset{Float64,2} = mat2ds(gmt_centroid_area(G_API[1], D, Int(isgeog(D))), geom=wkbPoint)
433+
ct.text = t # Texts will be plotted at the polygons centroids
434+
(CTRL.pocket_call[1] === nothing) ? (CTRL.pocket_call[1] = ct) : (CTRL.pocket_call[2] = ct)
435+
end
435436
append!(_cmd, ["pstext -R -J -F" * fnt * "+jMC"])
436437
return nothing
437438
end
438439

440+
# ---------------------------------------------------------------------------------------------------
441+
function fish_attrib_in_str(s::String)::String
442+
# Fish the contents of 'labels="attrib=???"'
443+
!(startswith(s, "att") && (contains(s, '=') || contains(s, ':'))) &&
444+
error("The labels option must be 'labels=\"att=???\"' or 'labels=\"attrib=???\"'")
445+
((ind = findfirst('=', s)) === nothing) && (ind = findfirst(':', s))
446+
s[ind+1:end]
447+
end
448+
439449
# ---------------------------------------------------------------------------------------------------
440450
function get_numeric_view()::Tuple{Float64, Float64}
441451
isempty(CURRENT_VIEW[1]) && error("No perspective setting available yet (CURRENT_VIEW is empty)")
@@ -502,7 +512,7 @@ end
502512
# ---------------------------------------------------------------------------------------------------
503513
function if_multicols(d, arg1, is3D::Bool)
504514
# If the input is a GMTdataset and 'multicol' is asked, split the DS into a vector of DS's
505-
(!MULTI_COL[1] && find_in_dict(d, [:multi :multicol :multicols], false)[1] === nothing) && return arg1
515+
(!MULTI_COL[1] && is_in_dict(d, [:multi :multicol :multicols]) === nothing) && return arg1
506516
is3D && (delete!(d, [:multi, :multicol, :multicols]); @warn("'multile coluns' in 3D plots are not allowed. Ignoring."))
507517
(isdataframe(arg1) || isODE(arg1)) && return arg1
508518
(isa(arg1, Vector{<:GMTdataset}) && (size(arg1,2) > 2+is3D)) && return arg1 # Play safe
@@ -616,7 +626,7 @@ function with_xyvar(d::Dict, arg1::GMTdataset, no_x::Bool=false)::Union{GMTdatas
616626
end
617627
isempty(ycv) && error("yvar option is non-sense.")
618628
(minimum(ycv) < 1 || maximum(ycv) > size(arg1,2)) && error("Col names not found in GMTdataset col names or exceed col count.")
619-
domulticol = ((val = find_in_dict(d::Dict, [:nomulticol])[1]) === nothing) ? true : false
629+
domulticol = ((is_in_dict(d::Dict, [:nomulticol]; del=true)) === nothing) ? true : false
620630
(domulticol) && (ismulticol = true)
621631
end
622632

@@ -954,10 +964,10 @@ function parse_opt_S(d::Dict, arg1, is3D::Bool=false)
954964
opt_S = " -S" * helper_arrows(d)
955965
end
956966
else
957-
val, symb = find_in_dict(d, [:ms :markersize :MarkerSize :size])
958-
(val !== nothing) && @warn("option *$(symb)* is ignored when either 'S' or 'symbol' options are used")
959-
val, symb = find_in_dict(d, [:marker :Marker :shape])
960-
(val !== nothing) && @warn("option *$(symb)* is ignored when either 'S' or 'symbol' options are used")
967+
symb = is_in_dict(d, [:ms :markersize :MarkerSize :size]; del=true)
968+
(symb !== nothing) && @warn("option *$(symb)* is ignored when either 'S' or 'symbol' options are used")
969+
symb = is_in_dict(d, [:marker :Marker :shape]; del=true)
970+
(symb !== nothing) && @warn("option *$(symb)* is ignored when either 'S' or 'symbol' options are used")
961971
end
962972
return arg1, opt_S
963973
end
@@ -1058,12 +1068,12 @@ function bar_group(d::Dict, cmd::String, opt_R::String, g_bar_fill::Vector{Strin
10581068
is_waterfall = false
10591069
is_hbar = occursin("-SB", cmd) # An horizontal bar plot
10601070

1061-
if ((val = find_in_dict(d, [:stack :stacked])[1]) !== nothing)
1071+
if ((val = hlp_desnany_str(d, [:stack :stacked])) !== "")
10621072
# Take this (two groups of 3 bars) [0 1 2 3; 1 2 3 4] and compute this (the same but stacked)
10631073
# [0 1 0; 0 3 1; 0 6 3; 1 2 0; 1 5 2; 1 9 4]
10641074
# Taking for example the first group, [0 1 0; 0 3 1; 0 6 3] this means:
10651075
# [|x=0 base=0, y=1|; |x=0 base=1, y=3|; |x=0, base=3, y=6]
1066-
is_waterfall = startswith(string(val)::String, "water")
1076+
is_waterfall = startswith(val, "water")
10671077
nl::Int = size(_arg,2)-1 # N layers in stack
10681078
tmp = zeros(size(_arg,1)*nl, 3)
10691079

@@ -1245,23 +1255,23 @@ function make_color_column(d::Dict, cmd::String, opt_i::String, len_cmd::Int, N_
12451255
# See if we got a CPT. If yes, there is quite some work to do if no color column provided in input data.
12461256
# N_ARGS will be == n_prev+1 when a -Ccpt was used. Otherwise they are equal.
12471257

1248-
mz, the_kw = find_in_dict(d, [:zcolor :markerz :mz])
1249-
if ((!(N_args > n_prev || len_cmd < length(cmd)) && mz === nothing) && !bar_ok) # No color request, so return right away
1258+
mz, the_kw = find_in_dict(d, [:zcolor :markerz :mz :level])
1259+
no_mz = (the_kw === Symbol()) # Means, no zcolor request
1260+
if ((!(N_args > n_prev || len_cmd < length(cmd)) && no_mz) && !bar_ok) # No color request, so return right away
12501261
return cmd, arg1, arg2, N_args, false
12511262
end
12521263

12531264
# Filled polygons with -Z don't need extra col
1254-
((val = find_in_dict(d, [:G :fill], false)[1]) == "+z") && return cmd, arg1, arg2, N_args, false
1265+
((val = hlp_desnany_str(d, [:G :fill], false)) == "+z") && return cmd, arg1, arg2, N_args, false
12551266

12561267
n_rows, n_col = get_sizes(arg1) # Deal with the matrix, DS & Vec{DS} cases
1257-
#(isa(mz, Int) && mz <= n_col && mz == 3+is3D) && return cmd, arg1, nothing, N_args, false # zcolor column is already in place
1258-
(isa(mz, Bool) && mz) && (mz = 1:n_rows)
1268+
(isa(mz, Bool) && mz) && (mz = collect(1:n_rows))
12591269

1260-
if ((mz !== nothing && length(mz)::Int != n_rows) || (mz === nothing && opt_i != ""))
1270+
if ((!no_mz && length(mz)::Int != n_rows) || (no_mz && opt_i != ""))
12611271
warn1 = string("Probably color column in '", the_kw, "' has incorrect dims (", length(mz), " vs $n_rows). Ignoring it.")
12621272
warn2 = "Plotting with color table requires adding one more column to the dataset but your 'incols'
12631273
option didn't do it, so you won't get what you expect. Try incols=\"0-1,1\" for 2D or \"=0-2,2\" for 3D plots"
1264-
(mz !== nothing) ? @warn(warn1) : @warn(warn2)
1274+
(!no_m) ? @warn(warn1) : @warn(warn2)
12651275
return cmd, arg1, arg2, N_args, true
12661276
end
12671277

@@ -1278,14 +1288,14 @@ function make_color_column(d::Dict, cmd::String, opt_i::String, len_cmd::Int, N_
12781288
return cmd, arg1, arg2, 2, true
12791289
end
12801290

1281-
make_color_column_(d, cmd, len_cmd, N_args, n_prev, is3D, got_Ebars, arg1, arg2, mz, n_col)
1291+
make_color_column_(d, cmd, len_cmd, N_args, n_prev, is3D, got_Ebars, arg1, arg2, !no_mz, mz, n_col)
12821292
end
12831293

12841294
# ---------------------------------------------------------------------------------------------------
1285-
function make_color_column_(d::Dict, cmd::String, len_cmd::Int, N_args::Int, n_prev::Int, is3D::Bool, got_Ebars::Bool, arg1, arg2, mz, n_col::Int)
1295+
function make_color_column_(d::Dict, cmd::String, len_cmd::Int, N_args::Int, n_prev::Int, is3D::Bool, got_Ebars::Bool, arg1, arg2, have_mz, mz, n_col::Int)
12861296
# Broke this out of make_color_column() to try to limit effect of invalidations but with questionable results.
12871297
if (n_col <= 2+is3D)
1288-
if (mz !== nothing)
1298+
if (have_mz)
12891299
if (isa(arg1,GMTdataset))
12901300
add2ds!(arg1, mz; name="Zcolor")
12911301
elseif (isa(arg1, Vector{<:GMTdataset}))
@@ -1298,7 +1308,7 @@ function make_color_column_(d::Dict, cmd::String, len_cmd::Int, N_args::Int, n_p
12981308
end
12991309
end
13001310
else
1301-
if (mz !== nothing) # Here we must insert the color col right after the coords
1311+
if (have_mz) # Here we must insert the color col right after the coords
13021312
if (isa(arg1,GMTdataset))
13031313
add2ds!(arg1, mz, 3+is3D; name="Zcolor")
13041314
elseif (isa(arg1, Vector{<:GMTdataset}))
@@ -1310,7 +1320,7 @@ function make_color_column_(d::Dict, cmd::String, len_cmd::Int, N_args::Int, n_p
13101320
end
13111321

13121322
if (N_args == n_prev) # No cpt transmitted, so need to compute one
1313-
if (mz !== nothing) mi::Float64, ma::Float64 = extrema(mz)
1323+
if (have_mz) mi::Float64, ma::Float64 = extrema(mz)
13141324
else
13151325
the_col = min(n_col,3)+is3D
13161326
(the_col > n_col) && (the_col = n_col) # Shitty logic before may have lead to this need.
@@ -1533,7 +1543,8 @@ function check_caller(d::Dict, cmd::String, opt_S::String, opt_W::String, caller
15331543
bar_type = 2; delete!(d, :hbar)
15341544
end
15351545
if (bar_type == 0 || bar_opts == "") # bar_opts == "" means only bar=true or hbar=true was used
1536-
gap::Float64 = ((val = find_in_dict(d, [:bargap])[1]) === nothing) ? 0.8 : (val > 1 ? (1.0 - val/100) : (1-val)) # Gap between bars in a group
1546+
val = hlp_desnany_float(d, [:bargap])
1547+
gap = (isnan(val)) ? 0.8 : (val > 1 ? (1.0 - val/100) : (1-val)) # Gap between bars in a group
15371548
opt = (haskey(d, :width)) ? add_opt(d, "", "", [:width]) : "$gap" # 0.8 is the default
15381549
_Stype = (bar_type == 2) ? " -SB" : " -Sb"
15391550
cmd *= _Stype * opt * "u"

src/utils_types.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2547,6 +2547,16 @@ function hlp_desnany_vstr(d, s)::Vector{String}
25472547
((val = find_in_dict(d, s)[1]) === nothing) ? String[] : (isa(val, String) ? [val] : val)
25482548
end
25492549

2550+
# ---------------------------------------------------------------------------------------------------
2551+
function hlp_desnany_int(d, s, default::Int=-999)::Int
2552+
((val = find_in_dict(d, s)[1]) === nothing) ? default : (isa(val, Bool) ? Int(val) : parse(Int, val))
2553+
end
2554+
2555+
# ---------------------------------------------------------------------------------------------------
2556+
function hlp_desnany_float(d, s)::Float64
2557+
((val = find_in_dict(d, s)[1]) === nothing) ? NaN : Float64(val)
2558+
end
2559+
25502560
# ---------------------------------------------------------------------------------------------------
25512561
function hlp_desnany_vfloat(d, s)::Vector{Float64}
25522562
((val = find_in_dict(d, s)[1]) === nothing) && return Float64[]

0 commit comments

Comments
 (0)