@@ -31,6 +31,8 @@ module UnicodePlot
3131 fix_ar : Bool ,
3232 out_stream : IO ? = nil ,
3333 ) : {Int32 , Int32 }
34+ return {0 , 0 } if nrows == 0 && ncols == 0
35+
3436 yppc, xppc = spy_canvas_pixel_per_char(canvas)
3537 canv_height = nrows.to_f64 / yppc
3638 canv_width = ncols.to_f64 / xppc
@@ -82,6 +84,7 @@ module UnicodePlot
8284
8385 {final_h.clamp(1 , Int32 ::MAX ), final_w.clamp(1 , Int32 ::MAX )}
8486 end
87+
8588 # ameba:enable Metrics/CyclomaticComplexity
8689
8790 def spy (
@@ -111,7 +114,6 @@ module UnicodePlot
111114 thousands_separator : Char = ' ' ,
112115 ) : Plot
113116 matrix = MatrixView .new(a)
114- raise ArgumentError .new(" a must not be empty" ) if matrix.empty?
115117
116118 nrows = matrix.nrows
117119 ncols = matrix.ncols
@@ -162,8 +164,9 @@ module UnicodePlot
162164 grid: false ,
163165 # Julia's spy passes canvas_kw: (height: 1 + nrow, width: 1 + ncol).
164166 # build_plot has no canvas_kw, so use widened limits to match the same mapping scale.
165- xlim: {1.0 , ncols.to_f64 + 2.0 },
166- ylim: {1.0 , nrows.to_f64 + 2.0 },
167+ # For 0x0 matrices, Julia uses xlim=[1,0]/ylim=[1,0] (inverted); Crystal maps this to {0.0,1.0}.
168+ xlim: ncols == 0 ? {0.0 , 1.0 } : {1.0 , ncols.to_f64 + 2.0 },
169+ ylim: nrows == 0 ? {0.0 , 1.0 } : {1.0 , nrows.to_f64 + 2.0 },
167170 xflip: xflip,
168171 yflip: yflip,
169172 unicode_exponent: unicode_exponent,
@@ -191,12 +194,26 @@ module UnicodePlot
191194 plot.xlabel = " #{ plot.nice_repr(vals.size) } #{ show_zeros ? " ⩵ 0" : " ≠ 0" } "
192195 end
193196
194- # Keep displayed axis endpoints identical to Julia's spy (1..ncol, 1..nrow) .
197+ # Keep displayed axis endpoints identical to Julia's spy.
195198 bc = ansi_color(border_color)
196- plot.label!(:bl , xflip ? nice_repr(ncols, unicode_exponent, thousands_separator) : " 1" , bc)
197- plot.label!(:br , xflip ? " 1" : nice_repr(ncols, unicode_exponent, thousands_separator), bc)
198- plot.label!(:l , plot.canvas.nrows, yflip ? nice_repr(nrows, unicode_exponent, thousands_separator) : " 1" , bc)
199- plot.label!(:l , 1 , yflip ? " 1" : nice_repr(nrows, unicode_exponent, thousands_separator), bc)
199+ x_left, x_right = matrix_horizontal_axis_labels(
200+ ncols,
201+ flip: xflip,
202+ unicode_exponent: unicode_exponent,
203+ thousands_separator: thousands_separator,
204+ zero_fallback_range: true ,
205+ )
206+ y_top, y_bottom = matrix_vertical_axis_labels(
207+ nrows,
208+ flip: yflip,
209+ unicode_exponent: unicode_exponent,
210+ thousands_separator: thousands_separator,
211+ zero_fallback_range: true ,
212+ )
213+ plot.label!(:bl , x_left, bc)
214+ plot.label!(:br , x_right, bc)
215+ plot.label!(:l , plot.canvas.nrows, y_top, bc)
216+ plot.label!(:l , 1 , y_bottom, bc)
200217
201218 plot
202219 end
0 commit comments