@@ -10,6 +10,74 @@ const SurfaceLikeCompat = isdefined(Makie, :SurfaceLike) ? Makie.SurfaceLike : U
1010
1111_paired (args... ) = map (x -> x isa Pair ? x : x => x, args)
1212
13+ struct DimLines{T,N,D<: DD.DimTuple ,O} <: DD.AbstractDimIndices{T,N}
14+ dims:: D
15+ order:: O
16+ end
17+ function DimLines (dims:: DD.DimTuple ; order= dims)
18+ @assert count (isintervals (dims)) == 1
19+ order = map (d -> basetypeof (d)(), order)
20+ T = typeof (_getline (dims, map (firstindex, dims)))
21+ N = length (dims)
22+ dims = N > 0 ? DD. _format (dims) : dims
23+ DimLines {T,N,typeof(dims),typeof(order)} (dims, order)
24+ end
25+
26+ Base. getindex (dp:: DimLines , i1:: Int , i2:: Int , Is:: Int... ) = _getline (dims (dp), (i1, i2, Is... ))
27+ Base. getindex (di:: DimLines{<:Any,1} , i:: Int ) = (dims (di, 1 )[i],)
28+ Base. getindex (di:: DimLines , i:: Int ) = di[Tuple (CartesianIndices (di)[i])... ]
29+
30+ function _getline (ds, I:: Tuple )
31+ D = map (rebuild, ds, I)
32+ # Get dim-wrapped point values at i1, I...
33+ intervaldim = only (dims (ds, isintervals))
34+ ods = otherdims (ds, intervaldim)
35+ bounds = intervalbounds (lookup (intervaldim), val (dims (D, intervaldim))... )
36+ return map (bounds) do b
37+ (b, map (getindex, dims (ds, ods), map (val, dims (D, ods)))... )
38+ end
39+ end
40+
41+ struct DimPolygons{T,N,D<: DD.DimTuple ,O} <: DD.AbstractDimIndices{T,N}
42+ dims:: D
43+ order:: O
44+ end
45+ function DimPolygons (dims:: DD.DimTuple ; order= dims)
46+ @assert count (isintervals (dims)) == 2 " num intervaldims $(count (isintervals (dims))) is not 2"
47+ order = map (d -> basetypeof (d)(), order)
48+ T = typeof (_getpolygon (dims, map (firstindex, dims)))
49+ N = length (dims)
50+ dims = N > 0 ? DD. _format (dims) : dims
51+ DimPolygons {T,N,typeof(dims),typeof(order)} (dims, order)
52+ end
53+
54+ Base. getindex (dp:: DimPolygons , i1:: Int , i2:: Int , Is:: Int... ) = _getpolygon (dims (dp), (i1, i2, Is... ))
55+ Base. getindex (di:: DimPolygons{<:Any,1} , i:: Int ) = (dims (di, 1 )[i],)
56+ Base. getindex (di:: DimPolygons , i:: Int ) = di[Tuple (CartesianIndices (di)[i])... ]
57+
58+ function _getpolygon (ds:: DD.DimTuple , I:: Tuple )
59+ D = map (rebuild, ds, I)
60+ # Get dim-wrapped point values at i1, I...
61+ intervaldims = dims (ds, isintervals)
62+ ods = otherdims (ds, intervaldims)
63+ bvs = map (intervaldims) do id
64+ rebuild (id, intervalbounds (lookup (id), val (dims (D, id))... ))
65+ end
66+ ovs = map (rebuild, ods, map (getindex, ods, val (dims (D, ods))))
67+ points = [
68+ _polypoint (ds, bvs, ovs, 1 , 1 ),
69+ _polypoint (ds, bvs, ovs, 1 , 2 ),
70+ _polypoint (ds, bvs, ovs, 2 , 2 ),
71+ _polypoint (ds, bvs, ovs, 2 , 1 ),
72+ _polypoint (ds, bvs, ovs, 1 , 1 ),
73+ ]
74+ return Makie. Polygon (Makie. LineString (points))
75+ end
76+ function _polypoint (order, (bs1, bs2), ovs, i, j)
77+ vs = (rebuild (bs1, val (bs1)[i]), rebuild (bs2, val (bs2)[j]), ovs... )
78+ Point (map (val, dims (vs, order)))
79+ end
80+
1381
1482# Shared docstrings: keep things consistent.
1583
59127# 1d PointBased
60128
61129# 1d plots are scatter by default
62- for (f1, f2) in _paired ( :plot => :scatter , :scatter , :lines , :scatterlines , :stairs , :stem , :barplot , :waterfall )
63- f1!, f2! = Symbol (f1, ' ! ' ), Symbol (f2 , ' !' )
130+ for f in ( :scatter , :lines , :scatterlines , :stairs , :stem , :barplot , :waterfall )
131+ f! = Symbol (f , ' !' )
64132 docstring = """
65- $f1 (A::AbstractDimArray{<:Any,1} ; attributes...)
133+ $f (A::AbstractDimVector ; attributes...)
66134
67- Plot a 1-dimensional `AbstractDimArray` with `Makie. $f2 `.
135+ Plot a 1-dimensional `AbstractDimArray` with `Makie`.
68136
69137 The X axis will be labelled with the dimension name and and use ticks from its lookup.
70138
71- $(_keyword_heading_doc (f1 ))
139+ $(_keyword_heading_doc (f ))
72140 $AXISLEGENDKW_DOC
73141 """
74142 @eval begin
75143 @doc $ docstring
76- function Makie. $f1 (A:: AbstractDimArray{<:Any,1} ; axislegendkw= (;), attributes... )
144+ function Makie. $f (A:: AbstractDimVector ; axislegendkw= (;), attributes... )
77145 args, merged_attributes = _pointbased1 (A, attributes)
78- p = Makie.$ f2 (args... ; merged_attributes... )
146+ p = Makie.$ f (args... ; merged_attributes... )
79147 axislegend (p. axis; merge= false , unique= false , axislegendkw... )
80148 return p
81149 end
82- function Makie. $f1 ! (axis, A:: AbstractDimArray{<:Any,1} ; axislegendkw= (;), attributes... )
150+ function Makie. $f ! (axis, A:: AbstractDimVector ; axislegendkw= (;), attributes... )
83151 args, merged_attributes = _pointbased1 (A, attributes; set_axis_attributes= false )
84- return Makie.$ f2 ! (axis, args... ; merged_attributes... )
152+ return Makie.$ f ! (axis, args... ; merged_attributes... )
85153 end
86154 end
87155end
88156
157+
158+ function Makie. linesegments (A:: AbstractDimVector ; axislegendkw= (;), attributes... )
159+ args, merged_attributes = _pointbased1 (A, attributes)
160+ lines = _interval_lines (A)
161+ p = Makie. linesegments (lines; merged_attributes... )
162+ axislegend (p. axis; merge= false , unique= false , axislegendkw... )
163+ return p
164+ end
165+
166+ function Makie. linesegments! (x, A:: AbstractDimVector ; attributes... )
167+ args, merged_attributes = _pointbased1 (A, attributes)
168+ lines = _interval_lines (A)
169+ return Makie. linesegments (x, lines; merged_attributes... )
170+ end
171+
172+ function _interval_lines (A:: AbstractDimVector )
173+ map (intervalbounds (only (dims (A))), A) do bounds, val
174+ T = promote_type (typeof (first (bounds)), typeof (last (bounds)), typeof (val))
175+ (T (bounds[1 ]), T (val)), (T (bounds[2 ]), T (val))
176+ end
177+ end
178+
179+ function Makie. plot (A:: AbstractDimVector ; kw... )
180+ only (isintervals (A)) ? Makie. linesegments (A; kw... ) : Makie. scatter (A; kw... )
181+ end
182+ function Makie. plot! (ax, A:: AbstractDimVector ; kw... )
183+ only (isintervals (A)) ? Makie. linesegments! (ax, A; kw... ) : Makie. scatter (axis, A; kw... )
184+ end
185+
89186function _pointbased1 (A, attributes; set_axis_attributes= true )
90187 # Array/Dimension manipulation
91188 A1 = _prepare_for_makie (A)
@@ -118,52 +215,85 @@ end
118215
119216# 2d SurfaceLike
120217
121- for (f1, f2) in _paired ( :plot => :heatmap , :heatmap , :image , :contour , :contourf , :spy , :surface )
122- f1!, f2! = Symbol (f1, ' ! ' ), Symbol (f2 , ' !' )
218+ for f in ( :heatmap , :image , :contour , :contourf , :spy , :surface )
219+ f! = Symbol (f , ' !' )
123220 docstring = """
124- $f1 (A::AbstractDimArray{<:Any,2} ; attributes...)
221+ $f (A::AbstractDimMatrix ; attributes...)
125222
126- Plot a 2-dimensional `AbstractDimArray` with `Makie.$f2 `.
223+ Plot a 2-dimensional `AbstractDimArray` with `Makie.$f `.
127224
128- $(_keyword_heading_doc (f1 ))
129- $(_xy (f1 ))
130- $(_maybe_colorbar_doc (f1 ))
225+ $(_keyword_heading_doc (f ))
226+ $(_xy (f ))
227+ $(_maybe_colorbar_doc (f ))
131228 """
132229 @eval begin
133230 @doc $ docstring
134- function Makie. $f1 (A:: AbstractDimArray{T,2} ;
231+ function Makie. $f (A:: AbstractDimMatrix ;
135232 x= nothing , y= nothing , colorbarkw= (;), attributes...
136233 ) where T
137234 replacements = _keywords2dimpairs (x, y)
138235 A1, A2, args, merged_attributes = _surface2 (A, attributes, replacements)
139- p = if $ (f1 == :surface )
236+ p = if $ (f == :surface )
140237 # surface is an LScene so we cant pass attributes
141- p = Makie.$ f2 (args... ; attributes... )
238+ p = Makie.$ f (args... ; attributes... )
142239 # And instead set axisnames manually
143240 p. axis. scene[OldAxis][:names , :axisnames ] = map (DD. label, DD. dims (A2))
144241 p
145242 else
146- Makie.$ f2 (args... ; merged_attributes... )
243+ Makie.$ f (args... ; merged_attributes... )
147244 end
148245 # Add a Colorbar for heatmaps and contourf
149- if T isa Real && $ (f1 in (:plot , :heatmap , :contourf ))
246+ if T isa Real && $ (f in (:plot , :heatmap , :contourf ))
150247 Colorbar (p. figure[1 , 2 ], p. plot;
151248 label= DD. label (A), colorbarkw...
152249 )
153250 end
154251 return p
155252 end
156- function Makie. $f1 ! (axis, A:: AbstractDimArray{<:Any,2} ;
253+ function Makie. $f ! (axis, A:: AbstractDimMatrix ;
157254 x= nothing , y= nothing , colorbarkw= (;), attributes...
158255 )
159256 replacements = _keywords2dimpairs (x, y)
160257 _, _, args, _ = _surface2 (A, attributes, replacements)
161258 # No ColourBar in the ! in-place versions
162- return Makie.$ f2 ! (axis, args... ; attributes... )
259+ return Makie.$ f ! (axis, args... ; attributes... )
163260 end
164261 end
165262end
166263
264+ function Makie. plot (A:: AbstractDimMatrix ; kw... )
265+ if all (isintervals (dims (A)))
266+ Makie. heatmap (A; kw... )
267+ elseif any (isintervals (A))
268+ Makie. linesegments (A; kw... )
269+ else
270+ Makie. scatter (A; kw... )
271+ end
272+ end
273+ function Makie. plot! (ax, A:: AbstractDimMatrix ; kw... )
274+ if all (isintervals (A))
275+ Makie. heatmap! (ax, A; kw... )
276+ elseif any (isintervals (A))
277+ Makie. linesegments! (ax, A; kw... )
278+ else
279+ Makie. scatter! (ax, A; kw... )
280+ end
281+ end
282+
283+ function Makie. linesegments (A:: AbstractDimArray ; axislegendkw= (;), attributes... )
284+ # args, merged_attributes = _pointbased1(A, attributes)
285+ lines = vec (collect (DimLines (A)))
286+ p = Makie. linesegments (lines; color= vec (A))# , merged_attributes...)
287+ # axislegend(p.axis; merge=false, unique=false, axislegendkw...)
288+ return p
289+ end
290+
291+ function Makie. linesegments! (x, A:: AbstractDimArray ; attributes... )
292+ # args, merged_attributes = _pointbased1(A, attributes)
293+ lines = collect (vec (DimLines (A)))
294+ return Makie. linesegments (x, lines; colors= vec (A))# , merged_attributes...)
295+ end
296+
167297function _surface2 (A, attributes, replacements)
168298 # Array/Dimension manipulation
169299 A1 = _prepare_for_makie (A, replacements)
@@ -188,34 +318,75 @@ end
188318
189319# 3d VolumeLike
190320
191- for (f1, f2) in _paired ( :plot => :volume , :volume , :volumeslices )
192- f1!, f2! = Symbol (f1, ' ! ' ), Symbol (f2 , ' !' )
321+ for f in ( :volume , :volumeslices )
322+ f! = Symbol (f , ' !' )
193323 docstring = """
194- $f1 (A::AbstractDimArray{<:Any,3}; attributes...)
324+ $f (A::AbstractDimArray{<:Any,3}; attributes...)
195325
196- Plot a 3-dimensional `AbstractDimArray` with `Makie.$f2 `.
326+ Plot a 3-dimensional `AbstractDimArray` with `Makie.$f `.
197327
198- $(_keyword_heading_doc (f1 ))
199- $(_xy (f1 ))
200- $(_z (f1 ))
328+ $(_keyword_heading_doc (f ))
329+ $(_xy (f ))
330+ $(_z (f ))
201331 """
202332 @eval begin
203333 @doc $ docstring
204- function Makie. $f1 (A:: AbstractDimArray{<:Any,3} ; x= nothing , y= nothing , z= nothing , attributes... )
334+ function Makie. $f (A:: AbstractDimArray{<:Any,3} ; x= nothing , y= nothing , z= nothing , attributes... )
205335 replacements = _keywords2dimpairs (x, y, z)
206336 A1, A2, args, merged_attributes = _volume3 (A, attributes, replacements)
207- p = Makie.$ f2 (args... ; merged_attributes... )
337+ p = Makie.$ f (args... ; merged_attributes... )
208338 p. axis. scene[OldAxis][:names , :axisnames ] = map (DD. label, DD. dims (A2))
209339 return p
210340 end
211- function Makie. $f1 ! (axis, A:: AbstractDimArray{<:Any,3} ; x= nothing , y= nothing , z= nothing , attributes... )
341+ function Makie. $f ! (axis, A:: AbstractDimArray{<:Any,3} ; x= nothing , y= nothing , z= nothing , attributes... )
212342 replacements = _keywords2dimpairs (x, y, z)
213343 _, _, args, _ = _volume3 (A, attributes, replacements)
214- return Makie.$ f2 ! (axis, args... ; attributes... )
344+ return Makie.$ f ! (axis, args... ; attributes... )
215345 end
216346 end
217347end
218348
349+ function Makie. plot (A:: AbstractDimArray{<:Any,3} ; kw... )
350+ if all (isintervals (dims (A)))
351+ Makie. volume (A; kw... )
352+ elseif count (isintervals (A)) == 2
353+ Makie. poly (A; kw... )
354+ elseif count (isintervals (A)) == 1
355+ Makie. linesegments (A; kw... )
356+ else
357+ Makie. scatter (A; kw... )
358+ end
359+ end
360+ function Makie. plot! (ax, A:: AbstractDimArray{<:Any,3} ; kw... )
361+ if all (isintervals (A))
362+ Makie. volume! (ax, A; kw... )
363+ elseif count (isintervals (A)) == 2
364+ Makie. poly! (ax, A; kw... )
365+ elseif count (isintervals (A)) == 1
366+ Makie. linesegments! (ax, A; kw... )
367+ else
368+ Makie. scatter! (ax, A; kw... )
369+ end
370+ end
371+
372+ function Makie. poly (A:: AbstractDimArray ; axislegendkw= (;), attributes... )
373+ # args, merged_attributes = _pointbased1(A, attributes)
374+ dps = DimPolygons (A)
375+ polys = vec (collect (dps))
376+ # TODO this doesn't plot properly?
377+ # All polygons plat on the same plane
378+ p = Makie. poly (polys; color= vec (A))# , merged_attributes...)
379+ axislegend (p. axis; merge= false , unique= false , axislegendkw... )
380+ return p
381+ end
382+
383+ function Makie. poly! (x, A:: AbstractDimArray ; attributes... )
384+ # args, merged_attributes = _pointbased1(A, attributes)
385+ polys = collect (vec (DimPolygons (A)))
386+ return Makie. poly (x, polys; colors= vec (A))# , merged_attributes...)
387+ end
388+
389+
219390function _volume3 (A, attributes, replacements)
220391 # Array/Dimension manipulation
221392 A1 = _prepare_for_makie (A, replacements)
0 commit comments