Skip to content

Commit 3fe0b44

Browse files
authored
Add spheres to plot3d (#1866)
1 parent 179578a commit 3fe0b44

4 files changed

Lines changed: 63 additions & 4 deletions

File tree

src/marker_name.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function get_marker_name(d::Dict, arg1, symbs::Vector{Symbol}, is3D::Bool, del::
1414
elseif (o == "j" || startswith(o, "rot")) opt = "j"; N = 3
1515
elseif (o == "M" || startswith(o, "Mat")) opt = "M"; N = 3
1616
elseif (o == "m" || startswith(o, "mat")) opt = "m"; N = 3
17+
elseif (o == "P" || startswith(o, "sph")) opt = "P"; N = 1
1718
elseif (o == "R" || startswith(o, "Rec")) opt = "R"; N = 3
1819
elseif (o == "r" || startswith(o, "rec")) opt = "r"; N = 2
1920
elseif (o == "V" || startswith(o, "Vec")) opt = "V"; N = 2
@@ -23,6 +24,7 @@ function get_marker_name(d::Dict, arg1, symbs::Vector{Symbol}, is3D::Bool, del::
2324
elseif (o == "W" || o == "Pie" || o == "Web" || o == "Wedge") opt = "W"; N = 2
2425
end
2526
if (N > 0) marca, arg1, msg = helper_markers(opt, t[2], arg1, N, cst) end
27+
(marca == "P") && (marca = "P$(t[2])")
2628
(msg != "") && error(msg)
2729
if (length(t) == 3 && isa(t[3], NamedTuple))
2830
if (marca == "w" || marca == "W") # Ex (spiderweb): marker=(:pie, [...], (inner=1,))
@@ -41,6 +43,7 @@ function get_marker_name(d::Dict, arg1, symbs::Vector{Symbol}, is3D::Bool, del::
4143
elseif (key == :K || key == :Custom) opt = "K"
4244
elseif (key == :k || key == :custom) opt = "k"
4345
elseif (key == :M || key == :Matang) opt = "M"
46+
elseif (key == :P || key == :sphere) opt = "P"
4447
elseif (key == :m || key == :matang) opt = "m"
4548
elseif (key == :geovec) opt = "="
4649
end
@@ -54,6 +57,10 @@ function get_marker_name(d::Dict, arg1, symbs::Vector{Symbol}, is3D::Bool, del::
5457
marca = opt * add_opt(t, (size=("", arg2str, 1), arrow=("", vector_attrib)))
5558
elseif (opt == "k" || opt == "K")
5659
marca = opt * add_opt(t, (custom="", size="/"))
60+
elseif (opt == "P")
61+
marca = opt * add_opt(t, (sphere=("", arg2str, 1), size=("", arg2str, 2), azim="+a", elev="+e", flat="_+f", nofill="_+n", no_fill="_+n"))
62+
(marca == "P") && (marca = "P7p") # Default size 7p if none given
63+
(marca[2] == '+') && (marca = "P7p" * marca[2:end]) # iden
5764
end
5865
else
5966
t1::String = string(t)
@@ -63,7 +70,9 @@ function get_marker_name(d::Dict, arg1, symbs::Vector{Symbol}, is3D::Bool, del::
6370
elseif (t1 == "a" || t1 == "*" || t1 == "star") marca = "a"
6471
elseif (t1 == "k" || t1 == "custom") marca = "k"
6572
elseif (t1 == "x" || t1 == "cross") marca = "x"
66-
elseif (is3D && (t1 == "u" || t1 == "cube")) marca = "u" # Must come before next line
73+
elseif (is3D)
74+
(t1 == "P" || t1 == "sphere") && (marca = "P")
75+
(t1 == "u" || t1 == "cube") && (marca = "u") # Must come before next line
6776
elseif (t1[1] == 'c') marca = "c"
6877
elseif (t1[1] == 'd') marca = "d" # diamond
6978
elseif (t1 == "g" || t1 == "octagon") marca = "g"

src/psxy.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ function parse_opt_S(d::Dict, arg1, is3D::Bool=false)
956956
opt_S = " -S" * marca
957957
# If data comes from a file, then no automatic symbol size is added
958958
op = lowercase(marca[1])
959-
def_size::String = (op == 'p') ? "2p" : "7p" # 'p' stands for symbol points, not units. Att 7p used in seismicity()
959+
def_size::String = (marca[1] == 'P') ? "" : ((op == 'p') ? "2p" : "7p") # 'p' stands for symbol points, not units. Att 7p used in seismicity()
960960
(!more_cols && arg1 !== nothing && !isa(arg1, GMTcpt) && !occursin(op, "bekmrvw")) && (opt_S *= def_size)
961961
elseif (haskey(d, :hexbin))
962962
inc::Float64 = parse(Float64, arg1.attrib["hexbin"])
@@ -1000,13 +1000,13 @@ function build_run_cmd(cmd, opt_B, opt_Gsymb, opt_ML, opt_S, opt_W, opt_Wmarker,
10001000

10011001
elseif (opt_W == "" && (opt_S != "" || opt_Gsymb != "")) # We have a symbol request
10021002
(opt_Wmarker != "" && opt_W == "") && (opt_Gsymb *= " -W" * opt_Wmarker) # reuse var name
1003-
(opt_ML != "") && (cmd *= opt_ML) # If we have a symbol outline pen
1003+
(opt_ML != "") && (cmd *= opt_ML) # If we have a symbol outline pen
10041004
_cmd = [cmd * opt_S * opt_Gsymb * opt_UVXY]
10051005

10061006
elseif (opt_W != "" && opt_S != "") # We have both line/polygon and a symbol
10071007
(occursin(opt_Gsymb, cmd)) && (opt_Gsymb = "")
10081008
c = lowercase(opt_S[4])
1009-
if (c == 'v' || c == 'm' || c == 'w' || c == '=' || c == 'q') # Are there more cases where the pen applies to the symbol?
1009+
if (c == 'v' || c == 'm' || c == 'w' || c == '=' || c == 'q' || c == 'p') # Are there more cases where the pen applies to the symbol?
10101010
_cmd = [cmd * opt_W * opt_S * opt_Gsymb * opt_UVXY]
10111011
else
10121012
(opt_Wmarker != "") && (opt_Wmarker = " -W" * opt_Wmarker) # Set Symbol edge color

src/utils.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ end
247247
# --------------------------------------------------------------------------------------------------
248248
# Incredibly Julia ignores the NaN nature and incredibly min(1,NaN) = NaN, so need to ... fck
249249
extrema_nan(A::AbstractArray{<:AbstractFloat}) = minimum_nan(A), maximum_nan(A)
250+
extrema_nodataval(A::AbstractArray{<:Real}, val) = minimum_nodataval(A, val), maximum_nodataval(A, val)
250251
extrema_nan(A) = extrema(A)
251252

252253
"""
@@ -299,6 +300,20 @@ function maximum_nan(A::AbstractArray{<:AbstractFloat})
299300
end
300301
maximum_nan(A) = maximum(A)
301302

303+
# Cases where a specific no-data value is used and therefore should be excluded from min/max calculations
304+
function minimum_nodataval(A::AbstractArray{<:Real}, val)
305+
(val == typemax(eltype(A))) && return minimum(A) # No need to check for no-data value
306+
mi = typemax(eltype(A))
307+
@inbounds for k in eachindex(A) mi = ifelse((A[k] != val), min(mi, A[k]), mi) end
308+
return mi
309+
end
310+
function maximum_nodataval(A::AbstractArray{<:Real}, val)
311+
(val == typemin(eltype(A))) && return maximum(A) # No need to check for no-data value
312+
ma = typemin(eltype(A))
313+
@inbounds for k in eachindex(A) ma = ifelse((A[k] != val), max(ma, A[k]), ma) end
314+
return ma
315+
end
316+
302317
function findmax_nan(x::AbstractVector{T}) where T
303318
# Since Julia doesn't ignore NaNs and prefer to return wrong results findmax is useless when data
304319
# has NaNs. We start by runing findmax() and only if max is NaN we fallback to a slower algorithm.
@@ -1563,3 +1578,31 @@ end
15631578
#include("tanakacontour.jl")
15641579
#include("shufflelabel.jl")
15651580

1581+
function cut_icons(; nome="", size=350)
1582+
nomes = "basemap blockmean blockmode blockmedian clip coast colorbar contour dimfilter events filter1d fitcircle gmt2kml gmtbinstats gmtconnect gmtconvert gmtdefaults gmtinfo gmtlogo gmtmath gmtregress gmtselect gmtset gmtsplit gmtspatial gmtvector gmtwhich grd2cpt grd2kml grd2xyz grdblend grdclip grdcontour grdconver grdcut grdedit grdfft grdfill grdfilter grdgradient grdhisteq grdimage grdinfo grdinterpolate grdlandmask grdmask grdmath grdmix grdpaste grdproject grdsample grdtrack grdtrend grdvector grdview grdvolume greenspline histogram image inset kml2gmt legend mapproject mask movie nearneighbor plot plot3d project psconvert rose sample1d simplify solar spectrum1d sphinterpolate sphdistance sphtriangulate sph2grd splitxyz subplot surface ternary text trend1d trend2d triangulate wiggle xyz2grd"
1583+
1584+
nomes = "band bar bar3 biplot boxplot bubblechart cornerplot ecdfplot feather fill_between lines marginalhist parallelplot scatter stem stairs triplot"
1585+
1586+
nomes = "coupe earthtide flexure gmtflexure gmtisf gpsgridder gravfft gravmag3d gravprisms grdflexure grdgravmag3d grdpmodeler grdredpol grdrotater grdseamount grdspotter hotspotter polar img2grd magref meca mgd77convert mgd77track rotconverter rotsmoother sac talwani2d talwani3d velo windbarbs originater pmodeler polespotter segy2grd segy segyz backtracker"
1587+
1588+
nomes = "ablines anaglyph append2fig arrows bezier coastlinesproj cart2pol cart2sph cpt4dcw contourf colorzones crop cubeplot lazread lazwrite decorated earthregions ecdfplot ecmwf ecmwf findpeaks gadm hband hlines imagesc maregrams meteosat mosaic okada orbits parkergrav parkermag pastplates pca pcolor piechart plotlinefit plotyy qqplot quiver radar scatter3 sealand seismicity slicecube stackgrids stereonet streamlines trisurf vband violin vlines weather wmsread whittaker geocoder inpolygon isoutlier linearfitxy mat2ds mat2grid mat2img leepacific lelandshade remotegrid theme whereami zonal_stats geodetic2enu gmtread gmtwrite graticules gridit hampel imshow ind2rgb inwhichpolygon rasterzones worldrectangular xyzw2cube date2doy doy2date getbyattrib info isnodata ode2ds regiongeog rescale worldrectcoast worldrectgrid gunique polygonlevels sph2cart uniqueind vecangles getprovider mapsize2region wmsinfo"
1589+
1590+
nomes = "autocor blendimg! era5vars grid2tri grightjoin isclockwise isotime2unix kmeans lazinfo listecmwfvars yeardecimal"
1591+
#nomes = "gmt_core gmt_data gmt_grids gmt_jlext gmt_plot gmt_sup"
1592+
1593+
nome !== "" && (nomes = nome)
1594+
pato = "C:/v/doc_t/GMTjl_doc/quarto_site/documentation/modules/assets/"
1595+
pato_in = pato * "e/"
1596+
1597+
for name in split(nomes)
1598+
name_out = pato * name * "_logo.jpg"
1599+
name_in = pato_in * name * ".png"
1600+
I = gdalread(name_in)
1601+
Iw = binarize(I)
1602+
CC = bwconncomp(Iw)
1603+
Ic = gdaltranslate(I, R=CC.bbox[1].ds_bbox)
1604+
Ir = imresize(Ic, size)
1605+
gmtwrite(name_out, mat2img(Ir[:,:,1:3],Ir))
1606+
println("Created: " * name_out)
1607+
end
1608+
end

test/test_avatars.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@
227227
scatter3!(x -> sin(x), y -> cos(y), 0:pi/50:10pi, Vd=dbg2)
228228
scatter3!(x -> sin(x)*cos(10x), y -> sin(y)*sin(10y), z -> cos(z), 0:pi/100:pi, Vd=dbg2)
229229

230+
plot3([3 3 3], R="0/6/0/6/0/6", JZ=4, p="135/45", S="P2c", G=:blue, W="0.2p,red", Vd=dbg2)
231+
plot3([3 3 3], R="0/6/0/6/0/6", JZ=4, p="135/45", marker=(:sphe, 2), G=:blue, W="0.2p,red", Vd=dbg2)
232+
plot3([3 3 3], R="0/6/0/6/0/6", JZ=4, p="135/45", marker=:sphere, mc=:blue, mec="0.2p,red", ms=2, Vd=dbg2)
233+
plot3([3 3 3], R="0/6/0/6/0/6", JZ=4, p="135/45", marker=(sphere=true, flat=true, azim=19), mc=:blue, mec="0.2p,red", Vd=dbg2)
234+
plot3([3 3 3], R="0/6/0/6/0/6", JZ=4, p="135/45", marker=(sphere=3, flat=true, azim=19), mc=:blue, mec="0.2p,red", Vd=dbg2)
235+
plot3([3 3 3], R="0/6/0/6/0/6", JZ=4, p="135/45", marker=(sphere=true, size=6, flat=true, azim=19), mc=:blue, mec="0.2p,red", Vd=dbg2)
236+
230237
println(" ARROWS")
231238
arrows([0 8.2 0 6], R="-2/4/0/9", arrow=(len=2,stop=1,shape=0.5,fill=:red), J=:X14, B=:a, pen="6p")
232239
arrows([0 8.2 0 6], R="-2/4/0/9", arrow=(len=2,start=:arrow,stop=:tail,shape=0.5), J=:X14, B=:a, pen="6p")

0 commit comments

Comments
 (0)