Skip to content

Commit 4f3a981

Browse files
committed
adding support for staircase plots, with unit tests
1 parent 793f5e9 commit 4f3a981

11 files changed

Lines changed: 356 additions & 1 deletion

example/ex_staircase_plot.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/env ruby
2+
3+
$LOAD_PATH << "#{__dir__}/../lib"
4+
require "unicode_plot"
5+
6+
# single plot at a time
7+
UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], style: :post).render
8+
9+
# pre: style
10+
UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], style: :pre).render
11+
12+
# Another single plot with title
13+
UnicodePlot.stairs([2, 3, 5, 6, 9], [2, 5, 3, 4, 2], title: "My Staircase Plot").render
14+
15+
# Two plots at a time.
16+
# Using an explicit limit because data for the 2nd plot is outside the bounds from the 1st plot
17+
plot = UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], title: "Two Staircases", xlim: [1,10] )
18+
UnicodePlot.stairs!(plot, [0, 3, 5, 6, 9], [2, 5, 3, 4, 0])
19+
plot.render
20+
21+

lib/unicode_plot.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@
2323
require 'unicode_plot/lineplot'
2424
require 'unicode_plot/histogram'
2525
require 'unicode_plot/scatterplot'
26+
require 'unicode_plot/stairs'

lib/unicode_plot/stairs.rb

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# coding: utf-8
2+
=begin
3+
stairs(x, y; kwargs...)
4+
5+
Description
6+
============
7+
8+
Draws a staircase plot on a new canvas.
9+
10+
The first (optional) vector `x` should contain the horizontal
11+
positions for all the points. The second vector `y` should then
12+
contain the corresponding vertical positions respectively. This
13+
means that the two vectors must be of the same length and
14+
ordering.
15+
16+
Usage
17+
======
18+
19+
stairs(x, y; style = :post, name = "", title = "", xlabel = "", ylabel = "", labels = true, border = :solid, margin = 3, padding = 1, color = :auto, width = 40, height = 15, xlim = (0, 0), ylim = (0, 0), canvas = BrailleCanvas, grid = true)
20+
21+
Arguments
22+
==========
23+
24+
- **`x`** : The horizontal position for each point.
25+
26+
- **`y`** : The vertical position for each point.
27+
28+
- **`style`** : Specifies where the transition of the stair takes
29+
plays. Can be either `:pre` or `:post`.
30+
31+
- **`name`** : Annotation of the current drawing to be displayed
32+
on the right.
33+
34+
$DOC_PLOT_PARAMS
35+
36+
- **`height`** : Number of character rows that should be used
37+
for plotting.
38+
39+
- **`xlim`** : Plotting range for the x axis.
40+
`(0, 0)` stands for automatic.
41+
42+
- **`ylim`** : Plotting range for the y axis.
43+
`(0, 0)` stands for automatic.
44+
45+
- **`canvas`** : The type of canvas that should be used for drawing.
46+
47+
- **`grid`** : If `true`, draws grid-lines at the origin.
48+
49+
Returns
50+
========
51+
52+
A plot object of type `Plot{T<:Canvas}`
53+
54+
Author(s)
55+
==========
56+
57+
- Christof Stocker (Github: https://github.com/Evizero)
58+
- Dominique (Github: https://github.com/dpo)
59+
60+
Examples
61+
=========
62+
63+
```julia-repl
64+
julia> stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], style = :post, title = "My Staircase Plot")
65+
My Staircase Plot
66+
┌────────────────────────────────────────┐
67+
7 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
68+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
69+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
70+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
71+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
72+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
73+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
74+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡄⠀⠀⠀⠀⢸│
75+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
76+
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
77+
│⠀⠀⠀⠀⠀⢸⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
78+
│⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
79+
│⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠧⠤⠤⠤⠤⠼│
80+
│⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
81+
1 │⣀⣀⣀⣀⣀⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
82+
└────────────────────────────────────────┘
83+
1 8
84+
```
85+
86+
See also
87+
=========
88+
89+
[`Plot`](@ref), [`scatterplot`](@ref), [`lineplot`](@ref),
90+
[`BrailleCanvas`](@ref), [`BlockCanvas`](@ref),
91+
[`AsciiCanvas`](@ref), [`DotCanvas`](@ref)
92+
=end
93+
module UnicodePlot
94+
95+
module_function def stairs(xvec, yvec, style: :post, **kw)
96+
x_vex, y_vex = compute_stair_lines(xvec, yvec, style: style)
97+
lineplot(x_vex, y_vex, **kw)
98+
end
99+
100+
module_function def stairs!(plot, xvec, yvec, style: :post, **kw)
101+
x_vex, y_vex = compute_stair_lines(xvec, yvec, style: style)
102+
lineplot!(plot, x_vex, y_vex, **kw)
103+
end
104+
105+
module_function def compute_stair_lines(x, y, style: :post)
106+
x_vex = Array.new(x.length * 2 - 1, 0)
107+
y_vex = Array.new(x.length * 2 - 1, 0)
108+
x_vex[0] = x[0]
109+
y_vex[0] = y[0]
110+
o = 0
111+
if style == :post
112+
(1 ... x.length).each do |i|
113+
x_vex[i + o] = x[i]
114+
x_vex[i + o + 1] = x[i]
115+
y_vex[i + o] = y[i-1]
116+
y_vex[i + o + 1] = y[i]
117+
o += 1
118+
end
119+
elsif style == :pre
120+
(1 ... x.length).each do |i|
121+
x_vex[i + o] = x[i-1]
122+
x_vex[i + o + 1] = x[i]
123+
y_vex[i + o] = y[i]
124+
y_vex[i + o + 1] = y[i]
125+
o += 1
126+
end
127+
end
128+
return [x_vex, y_vex]
129+
end
130+
131+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
 Hellohow areyou?
2+
 ┌──────────┐
3+
7 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
4+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
5+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
6+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
7+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
8+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼│
9+
 │⠀⠀⠀⠀⠀⠀⠀⢀⠜⢸│
10+
 │⠀⠀⠀⠀⡤⠤⢤⠮⢤⢸│
11+
 │⠀⠀⠀⠀⡇⢠⠊⠀⢸⢸│
12+
 │⠀⠀⠀⠀⣧⠃⠀⠀⢸⢸│
13+
 │⠀⡏⠉⡹⠁⠀⠀⠀⢸⢸│
14+
 │⠀⡇⡰⠁⠀⠀⠀⠀⢸⢸│
15+
 │⠀⡟⠀⠀⠀⠀⠀⠀⠸⠼│
16+
 │⡜⡇⠀⠀⠀⠀⠀⠀⠀⠀│
17+
1 │⣀⡇⠀⠀⠀⠀⠀⠀⠀⠀│
18+
 └──────────┘
19+
 Hellohow areyou?
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
 ┌────────────────────────────────────────┐
2+
7000 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
3+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
4+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
5+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
6+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
7+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
8+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
9+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
10+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
11+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
12+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
13+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
14+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
15+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
16+
0 │⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣸│
17+
 └────────────────────────────────────────┘
18+
 1  8
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
 Foo
2+
 ┌────────────────────────────────────────┐
3+
7 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢸│ 1
4+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢸│ 2
5+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢸│
6+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⢸⢸│
7+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸⢸│
8+
 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸⢸│
9+
 │⠀⠀⠀⠀⢰⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠚⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸⢸│
10+
 │⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡧⡄⠀⠀⠀⢸⢸│
11+
 │⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⣇⣀⣀⣀⣸⢸│
12+
 │⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
13+
 │⠀⠀⠀⠀⢸⢸⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
14+
 │⠒⠒⠒⠒⠚⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⢸│
15+
 │⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠧⠤⠤⠤⠤⠼│
16+
 │⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
17+
1 │⣀⣀⣀⣀⣀⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
18+
 └────────────────────────────────────────┘
19+
 1  8
20+
 x

0 commit comments

Comments
 (0)