1+ using UnicodePlots
2+ export recurrenceplot, coordinates, grayscale
13# ########################################
24# Text-based plotting
35# ########################################
46"""
5- scatterdata(R::ARM ) -> xs, ys
6- Transform the data of a recurrence matrix to scatter data `xs, ys` .
7+ coordinates(R ) -> xs, ys
8+ Return the coordinates of the recurrence points of `R` (in indices) .
79"""
8- function scatterdata (R:: ARM ) # TODO : scan every ÷100 elements depending on size ?
10+ function coordinates (R:: ARM ) # TODO : allow scan every ÷100 elements?
911 rows = rowvals (R)
1012 is = zeros (Int, nnz (R))
1113 js = zeros (Int, nnz (R))
@@ -21,16 +23,14 @@ function scatterdata(R::ARM) # TODO: scan every ÷100 elements depending on size
2123 return is, js
2224end
2325
24- using UnicodePlots
25- export textrecurrenceplot
26-
27- textrecurrenceplot (R:: ARM ; kwargs... ) = textrecurrenceplot (stdout , R:: ARM ; kwargs... )
26+ recurrenceplot (R:: ARM ; kwargs... ) = recurrenceplot (stdout , R:: ARM ; kwargs... )
2827
2928"""
30- textrecurrenceplot ([io,] R; minh = 25, maxh = 0.5, ascii, kwargs...) -> u
29+ recurrenceplot ([io,] R; minh = 25, maxh = 0.5, ascii, kwargs...) -> u
3130
32- Obtain a text-scatterplot representation of a recurrence matrix `R` to be displayed in
33- `io` (by default `stdout`). The matrix spans at minimum `minh` rows and at maximum
31+ Create a text-based scatterplot representation of a recurrence matrix `R` to be displayed in
32+ `io` (by default `stdout`) using `UnicodePlots`.
33+ The matrix spans at minimum `minh` rows and at maximum
3434`maxh*displaysize(io)[1]` (i.e. by default half the display).
3535As we always try to plot in equal aspect ratio, if the width of the plot is even less,
3636the minimum height is dictated by the width.
@@ -40,10 +40,11 @@ The keyword `ascii::Bool` can ensure that all elements of the plot are ASCII cha
4040
4141The rest of the `kwargs` are propagated into `UnicodePlots.scatterplot`.
4242
43- Internally this function calls `RecurrenceAnalysis.scatterdata` to transform
44- a recurrence matrix into scatter data.
43+ Notice that the accuracy of this function drops drastically for matrices whose size
44+ is significantly bigger than the width and height of the display (assuming each
45+ index of the matrix is one character).
4546"""
46- function textrecurrenceplot (io:: IO , R:: ARM ; minh = 25 , maxh = 0.5 , ascii = nothing , kwargs... )
47+ function recurrenceplot (io:: IO , R:: ARM ; minh = 25 , maxh = 0.5 , ascii = nothing , kwargs... )
4748 @assert maxh ≤ 1
4849 h, w = displaysize (io)
4950 h = max (minh, round (Int, maxh * h)) # make matrix as long as half the screen (but not too short)
@@ -54,7 +55,7 @@ function textrecurrenceplot(io::IO, R::ARM; minh = 25, maxh = 0.5, ascii = nothi
5455 w = round (Int, h* s)
5556 end
5657
57- is, js = scatterdata (R)
58+ is, js = coordinates (R)
5859 n, m = size (R)
5960
6061 if ascii == true
@@ -85,7 +86,7 @@ function textrecurrenceplot(io::IO, R::ARM; minh = 25, maxh = 0.5, ascii = nothi
8586end
8687
8788function Base. show (io:: IO , :: MIME"text/plain" , R:: ARM )
88- a = textrecurrenceplot (io, R)
89+ a = recurrenceplot (io, R)
8990 show (io, a)
9091end
9192
@@ -103,7 +104,7 @@ function checkgridsize(width::T, height::T, dims::Tuple{T,T}) where T<:Integer
103104 (height,width- 1 ) => height/ (width- 1 ))
104105 distances = Dict (d=> (r- ratio) for (d,r) in intratios)
105106 distancesigns = sign .(collect (values (distances)))
106- if all (x -> x >= 0 , distancesigns) || all (x -> x <= 0 , distancesigns)
107+ if all (R -> R >= 0 , distancesigns) || all (R -> R <= 0 , distancesigns)
107108 width_adj = round (Integer, height* dims[1 ]/ dims[2 ])
108109 height_adj = round (Integer, width* dims[2 ]/ dims[1 ])
109110 width = min (width, width_adj)
@@ -124,21 +125,19 @@ function overlapgrid(m::T, n::T) where T<:Integer
124125end
125126
126127# Calculate the level of "gray" (0=white, 1=black) corresponding to a matrix block
127- function block2grayscale (x , rind:: Tuple{T,T} , cind:: Tuple{T,T} ) where T<: Integer
128- submat = @view x [rind[1 ]: rind[2 ], cind[1 ]: cind[2 ]]
128+ function block2grayscale (R , rind:: Tuple{T,T} , cind:: Tuple{T,T} ) where T<: Integer
129+ submat = @view R [rind[1 ]: rind[2 ], cind[1 ]: cind[2 ]]
129130 ratio = count (! iszero, submat)/ prod (size (submat))
130131end
131132
132133"""
133- recurrenceplot(x [, bwcode]; width::Int, height::Int, exactsize=false)
134+ grayscale(R [, bwcode]; width::Int, height::Int, exactsize=false)
134135
135- Transform the recurrence matrix `x ` into a full matrix suitable for plotting as a
136- grayscale image. By default it returns a matrix with the same size as `x `,
136+ Transform the recurrence matrix `R ` into a full matrix suitable for plotting as a
137+ grayscale image. By default it returns a matrix with the same size as `R `,
137138but switched axes, containing "black" values in the cells that represent recurrent points,
138- and "white" values in the empty cells.
139-
140- **This function does not do any plotting!** You have to use the return value with
141- the plotting library of your choice.
139+ and "white" values in the empty cells and interpolating in-between for cases with
140+ both recurrent and empty cells, see below.
142141
143142The numeric codes for black and white are given in a 2-element tuple as a second
144143optional argument. Its default value is `(0.0, 1.0)`, i.e. black is coded as `0.0`
@@ -155,28 +154,31 @@ proportional to the original matrix, such that the returned matrix fits into a
155154matrix of the given dimensions. This automatic adjustment can be disabled by
156155passing the keyword argument `exactsize=true`.
157156
158- If the image has different dimensions than `x `, the cells of `x ` are distributed
157+ If the image has different dimensions than `R `, the cells of `R ` are distributed
159158in a grid with the size of the image, and a gray level between white and black
160159is calculated for each element of the grid, proportional to the number of
161160recurrent points contained in it. The levels of gray are coded as numbers of the
162161same type as the black and white codes.
162+
163+ It is advised to use `width, height` arguments for large matrices otherwise
164+ plots using functions like e.g. `imshow` could be misleading.
163165"""
164- function recurrenceplot (x , bwcode:: Tuple{TT,T} = (0.0 ,1.0 );
166+ function grayscale (R , bwcode:: Tuple{TT,T} = (0.0 ,1.0 );
165167 exactsize= false , kwargs... ) where {TT<: Real , T<: Real }
166168
167- dims = size (x )
169+ dims = size (R )
168170 kwargs = Dict (kwargs)
169171 if haskey (kwargs, :width ) && ! haskey (kwargs, :height )
170172 width = Integer (kwargs[:width ])
171173 height = round (Integer, width* dims[2 ]/ dims[1 ])
172- return recurrenceplot (x , bwcode; width= width, height= height)
174+ return grayscale (R , bwcode; width= width, height= height)
173175 elseif haskey (kwargs, :height ) && ! haskey (kwargs, :width )
174176 height = Integer (kwargs[:height ])
175177 width = round (Integer, height* dims[1 ]/ dims[2 ])
176- return recurrenceplot (x , bwcode; width= width, height= height)
178+ return grayscale (R , bwcode; width= width, height= height)
177179 elseif ! haskey (kwargs, :width ) || ! haskey (kwargs, :height )
178180 width, height = Integer .(dims)
179- return recurrenceplot (x , bwcode; width= width, height= height)
181+ return grayscale (R , bwcode; width= width, height= height)
180182 end
181183 if exactsize
182184 width, height = Integer (kwargs[:width ]), Integer (kwargs[:height ])
@@ -190,7 +192,7 @@ function recurrenceplot(x, bwcode::Tuple{TT,T}=(0.0,1.0);
190192 p = zeros (height, width)
191193 # Fill img switching dimensions
192194 for c= 1 : width, r= 1 : height
193- p[r,c] = block2grayscale (x , rows[c], cols[end - r+ 1 ])
195+ p[r,c] = block2grayscale (R , rows[c], cols[end - r+ 1 ])
194196 end
195197 # Normalize values
196198 p ./= maximum (p)
0 commit comments