Skip to content

Commit 0228b7f

Browse files
committed
Enhance plotting library with experimental Time x-axis support
1 parent 320027f commit 0228b7f

20 files changed

Lines changed: 1416 additions & 1188 deletions

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ lineplot!(p, x, x.map { |v| Math.log(v) }, name: "ln(x)", color: :red)
111111
puts p
112112
```
113113

114+
### Time x-axis (experimental)
115+
116+
`lineplot` and `stairs` can accept `Array(Time)` for the x-axis. This API is experimental and currently requires an explicit Crystal `Time#to_s` format string:
117+
118+
```crystal
119+
dates = (0..10).map { |i| Time.utc(2020, 1, 1) + i.days }
120+
puts lineplot(dates, dates.map_with_index { |_, i| i.to_f }, format: "%F")
121+
```
122+
114123
### Options
115124

116125
| Option | Description |

examples/contourplot.cr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ include UnicodePlot
55
# Basic contour plot
66
x = (-20..20).map { |i| i.to_f64 / 10.0 }
77
y = (-20..20).map { |i| i.to_f64 / 10.0 }
8-
z = y.map do |yv|
9-
x.map do |xv|
8+
z = y.map do |y_value|
9+
x.map do |x_value|
1010
# Saddle-like field
11-
xv * xv - yv * yv
11+
x_value * x_value - y_value * y_value
1212
end
1313
end
1414

@@ -25,10 +25,10 @@ puts p
2525
puts
2626

2727
# Overlay with contourplot!
28-
z2 = y.map do |yv|
29-
x.map do |xv|
28+
z2 = y.map do |y_value|
29+
x.map do |x_value|
3030
# Shifted Gaussian bump
31-
Math.exp(-((xv - 0.7) ** 2 + (yv + 0.4) ** 2) / 0.25)
31+
Math.exp(-((x_value - 0.7) ** 2 + (y_value + 0.4) ** 2) / 0.25)
3232
end
3333
end
3434

spec/reference/barplot_spec.cr

Lines changed: 141 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,146 @@
11
require "../support/reference_helpers"
22

33
describe "Julia reference output compatibility - barplot" do
4-
describe "barplot" do
5-
it "matches barplot/default" do
6-
p = UnicodePlot.barplot(["bar", "foo"], [23.0, 37.0])
7-
test_ref("barplot/default.txt", p)
4+
describe "barplot" do
5+
it "matches barplot/default" do
6+
p = UnicodePlot.barplot(["bar", "foo"], [23.0, 37.0])
7+
test_ref("barplot/default.txt", p)
8+
end
9+
10+
it "matches barplot/default2 (with barplot! appended)" do
11+
p = UnicodePlot.barplot(["bar", "foo"], [23.0, 37.0])
12+
UnicodePlot.barplot!(p, ["zoom"], [90.0])
13+
test_ref("barplot/default2.txt", p)
14+
end
15+
16+
it "matches barplot/nocolor" do
17+
p = UnicodePlot.barplot(["bar", "foo"], [23.0, 37.0])
18+
test_ref("barplot/nocolor.txt", p)
19+
end
20+
21+
it "matches barplot/ranges" do
22+
p = UnicodePlot.barplot(["2", "3", "4", "5", "6"], [11.0, 12.0, 13.0, 14.0, 15.0])
23+
test_ref("barplot/ranges.txt", p)
24+
end
25+
26+
it "matches barplot/ranges2" do
27+
p = UnicodePlot.barplot(["2", "3", "4", "5", "6"], [11.0, 12.0, 13.0, 14.0, 15.0])
28+
UnicodePlot.barplot!(p, ["9", "10"], [20.0, 21.0])
29+
test_ref("barplot/ranges2.txt", p)
30+
end
31+
32+
it "matches barplot/parameters1" do
33+
p = UnicodePlot.barplot(
34+
["Paris", "New York", "Moskau", "Madrid"],
35+
[2.244, 8.406, 11.92, 3.165],
36+
title: "Relative sizes of cities",
37+
xlabel: "population [in mil]",
38+
color: :blue,
39+
margin: 7,
40+
padding: 3,
41+
)
42+
test_ref("barplot/parameters1.txt", p)
43+
end
44+
45+
it "matches barplot/parameters1_nolabels" do
46+
p = UnicodePlot.barplot(
47+
["Paris", "New York", "Moskau", "Madrid"],
48+
[2.244, 8.406, 11.92, 3.165],
49+
title: "Relative sizes of cities",
50+
xlabel: "population [in mil]",
51+
color: :blue,
52+
margin: 7,
53+
padding: 3,
54+
labels: false,
55+
)
56+
test_ref("barplot/parameters1_nolabels.txt", p)
57+
end
58+
59+
it "matches barplot/parameters2" do
60+
p = UnicodePlot.barplot(
61+
["Paris", "New York", "Moskau", "Madrid"],
62+
[2.244, 8.406, 11.92, 3.165],
63+
title: "Relative sizes of cities",
64+
xlabel: "population [in mil]",
65+
color: :yellow,
66+
border: :solid,
67+
symbols: ['='],
68+
width: 60,
69+
)
70+
test_ref("barplot/parameters2.txt", p)
71+
end
72+
73+
it "matches barplot/edgecase_zeros" do
74+
p = UnicodePlot.barplot(["5", "4", "3", "2", "1"], [0.0, 0.0, 0.0, 0.0, 0.0])
75+
test_ref("barplot/edgecase_zeros.txt", p)
76+
end
77+
78+
it "matches barplot/edgecase_onelarge" do
79+
p = UnicodePlot.barplot(["a", "b", "c", "d"], [1.0, 1.0, 1.0, 1_000_000.0])
80+
test_ref("barplot/edgecase_onelarge.txt", p)
81+
end
82+
83+
it "matches barplot/col1 (8-bit terminal color, ANSI stripped)" do
84+
p = UnicodePlot.barplot(["B", "A"], [2.0, 1.0], color: 9_i32)
85+
test_ref("barplot/col1.txt", p)
86+
end
87+
88+
it "matches barplot/log10" do
89+
p = UnicodePlot.barplot(
90+
["a", "b", "c", "d", "e"],
91+
[0.0, 1.0, 10.0, 100.0, 1_000.0],
92+
title: "Logscale Plot",
93+
xscale: :log10,
94+
)
95+
test_ref("barplot/log10.txt", p)
96+
end
97+
98+
it "matches barplot/log10_label" do
99+
p = UnicodePlot.barplot(
100+
["a", "b", "c", "d", "e"],
101+
[0.0, 1.0, 10.0, 100.0, 1_000.0],
102+
title: "Logscale Plot",
103+
xlabel: "custom label",
104+
xscale: :log10,
105+
)
106+
test_ref("barplot/log10_label.txt", p)
107+
end
108+
109+
it "matches barplot/col2 (RGB tuple color)" do
110+
p = UnicodePlot.barplot(["B", "A"], [2.0, 1.0], color: {200, 50, 0})
111+
test_ref("barplot/col2.txt", p)
112+
end
113+
114+
it "matches barplot/colors (per-bar color vector)" do
115+
p = UnicodePlot.barplot(
116+
["a", "b", "c", "d", "e"],
117+
[20.0, 30.0, 60.0, 50.0, 40.0],
118+
color: [:red, :green, :blue, :yellow, :normal],
119+
)
120+
test_ref("barplot/colors.txt", p)
121+
end
122+
123+
it "matches barplot/maximum_series1" do
124+
p = UnicodePlot.barplot(
125+
["1", "2", "3"],
126+
[1.0, 2.0, 3.0],
127+
color: :blue,
128+
name: "1ˢᵗ series",
129+
maximum: 10.0,
130+
)
131+
test_ref("barplot/maximum_series1.txt", p)
132+
end
133+
134+
it "matches barplot/maximum_series2" do
135+
p = UnicodePlot.barplot(
136+
["1", "2", "3"],
137+
[1.0, 2.0, 3.0],
138+
color: :blue,
139+
name: "1ˢᵗ series",
140+
maximum: 10.0,
141+
)
142+
UnicodePlot.barplot!(p, ["4", "5", "6"], [6.0, 1.0, 10.0], color: :red, name: "2ⁿᵈ series")
143+
test_ref("barplot/maximum_series2.txt", p)
144+
end
8145
end
9-
10-
it "matches barplot/default2 (with barplot! appended)" do
11-
p = UnicodePlot.barplot(["bar", "foo"], [23.0, 37.0])
12-
UnicodePlot.barplot!(p, ["zoom"], [90.0])
13-
test_ref("barplot/default2.txt", p)
14-
end
15-
16-
it "matches barplot/nocolor" do
17-
p = UnicodePlot.barplot(["bar", "foo"], [23.0, 37.0])
18-
test_ref("barplot/nocolor.txt", p)
19-
end
20-
21-
it "matches barplot/ranges" do
22-
p = UnicodePlot.barplot(["2", "3", "4", "5", "6"], [11.0, 12.0, 13.0, 14.0, 15.0])
23-
test_ref("barplot/ranges.txt", p)
24-
end
25-
26-
it "matches barplot/ranges2" do
27-
p = UnicodePlot.barplot(["2", "3", "4", "5", "6"], [11.0, 12.0, 13.0, 14.0, 15.0])
28-
UnicodePlot.barplot!(p, ["9", "10"], [20.0, 21.0])
29-
test_ref("barplot/ranges2.txt", p)
30-
end
31-
32-
it "matches barplot/parameters1" do
33-
p = UnicodePlot.barplot(
34-
["Paris", "New York", "Moskau", "Madrid"],
35-
[2.244, 8.406, 11.92, 3.165],
36-
title: "Relative sizes of cities",
37-
xlabel: "population [in mil]",
38-
color: :blue,
39-
margin: 7,
40-
padding: 3,
41-
)
42-
test_ref("barplot/parameters1.txt", p)
43-
end
44-
45-
it "matches barplot/parameters1_nolabels" do
46-
p = UnicodePlot.barplot(
47-
["Paris", "New York", "Moskau", "Madrid"],
48-
[2.244, 8.406, 11.92, 3.165],
49-
title: "Relative sizes of cities",
50-
xlabel: "population [in mil]",
51-
color: :blue,
52-
margin: 7,
53-
padding: 3,
54-
labels: false,
55-
)
56-
test_ref("barplot/parameters1_nolabels.txt", p)
57-
end
58-
59-
it "matches barplot/parameters2" do
60-
p = UnicodePlot.barplot(
61-
["Paris", "New York", "Moskau", "Madrid"],
62-
[2.244, 8.406, 11.92, 3.165],
63-
title: "Relative sizes of cities",
64-
xlabel: "population [in mil]",
65-
color: :yellow,
66-
border: :solid,
67-
symbols: ['='],
68-
width: 60,
69-
)
70-
test_ref("barplot/parameters2.txt", p)
71-
end
72-
73-
it "matches barplot/edgecase_zeros" do
74-
p = UnicodePlot.barplot(["5", "4", "3", "2", "1"], [0.0, 0.0, 0.0, 0.0, 0.0])
75-
test_ref("barplot/edgecase_zeros.txt", p)
76-
end
77-
78-
it "matches barplot/edgecase_onelarge" do
79-
p = UnicodePlot.barplot(["a", "b", "c", "d"], [1.0, 1.0, 1.0, 1_000_000.0])
80-
test_ref("barplot/edgecase_onelarge.txt", p)
81-
end
82-
83-
it "matches barplot/col1 (8-bit terminal color, ANSI stripped)" do
84-
p = UnicodePlot.barplot(["B", "A"], [2.0, 1.0], color: 9_i32)
85-
test_ref("barplot/col1.txt", p)
86-
end
87-
88-
it "matches barplot/log10" do
89-
p = UnicodePlot.barplot(
90-
["a", "b", "c", "d", "e"],
91-
[0.0, 1.0, 10.0, 100.0, 1_000.0],
92-
title: "Logscale Plot",
93-
xscale: :log10,
94-
)
95-
test_ref("barplot/log10.txt", p)
96-
end
97-
98-
it "matches barplot/log10_label" do
99-
p = UnicodePlot.barplot(
100-
["a", "b", "c", "d", "e"],
101-
[0.0, 1.0, 10.0, 100.0, 1_000.0],
102-
title: "Logscale Plot",
103-
xlabel: "custom label",
104-
xscale: :log10,
105-
)
106-
test_ref("barplot/log10_label.txt", p)
107-
end
108-
109-
it "matches barplot/col2 (RGB tuple color)" do
110-
p = UnicodePlot.barplot(["B", "A"], [2.0, 1.0], color: {200, 50, 0})
111-
test_ref("barplot/col2.txt", p)
112-
end
113-
114-
it "matches barplot/colors (per-bar color vector)" do
115-
p = UnicodePlot.barplot(
116-
["a", "b", "c", "d", "e"],
117-
[20.0, 30.0, 60.0, 50.0, 40.0],
118-
color: [:red, :green, :blue, :yellow, :normal],
119-
)
120-
test_ref("barplot/colors.txt", p)
121-
end
122-
123-
it "matches barplot/maximum_series1" do
124-
p = UnicodePlot.barplot(
125-
["1", "2", "3"],
126-
[1.0, 2.0, 3.0],
127-
color: :blue,
128-
name: "1ˢᵗ series",
129-
maximum: 10.0,
130-
)
131-
test_ref("barplot/maximum_series1.txt", p)
132-
end
133-
134-
it "matches barplot/maximum_series2" do
135-
p = UnicodePlot.barplot(
136-
["1", "2", "3"],
137-
[1.0, 2.0, 3.0],
138-
color: :blue,
139-
name: "1ˢᵗ series",
140-
maximum: 10.0,
141-
)
142-
UnicodePlot.barplot!(p, ["4", "5", "6"], [6.0, 1.0, 10.0], color: :red, name: "2ⁿᵈ series")
143-
test_ref("barplot/maximum_series2.txt", p)
144-
end
145-
end
146-
147146
end

0 commit comments

Comments
 (0)