Module: UnicodePlot + + + +
+-
+
- Defined in: +
- src/lib/unicode_plot/plot.rb,
+ src/lib/unicode_plot/utils.rb,
src/lib/unicode_plot/canvas.rb,
src/lib/unicode_plot/barplot.rb,
src/lib/unicode_plot/boxplot.rb,
src/lib/unicode_plot/version.rb,
src/lib/unicode_plot/lineplot.rb,
src/lib/unicode_plot/renderer.rb,
src/lib/unicode_plot/grid_plot.rb,
src/lib/unicode_plot/histogram.rb,
src/lib/unicode_plot/dot_canvas.rb,
src/lib/unicode_plot/densityplot.rb,
src/lib/unicode_plot/scatterplot.rb,
src/lib/unicode_plot/ascii_canvas.rb,
src/lib/unicode_plot/lookup_canvas.rb,
src/lib/unicode_plot/braille_canvas.rb,
src/lib/unicode_plot/density_canvas.rb,
src/lib/unicode_plot/styled_printer.rb,
src/lib/unicode_plot/value_transformer.rb +
+
Defined Under Namespace
++ + + Modules: BorderMaps, BorderPrinter, StyledPrinter, Utils, ValueTransformer, Version + + + + Classes: AsciiCanvas, Barplot, Boxplot, BrailleCanvas, Canvas, DensityCanvas, DotCanvas, GridPlot, Lineplot, LookupCanvas, Plot, Renderer, Scatterplot + + +
+ + ++ Constant Summary + collapse +
+ +-
+
+
- VERSION = + + +
"0.0.3"
+
+ - BORDER_MAP = + + +
{ + solid: BorderMaps::BORDER_SOLID, + corners: BorderMaps::BORDER_CORNERS, + barplot: BorderMaps::BORDER_BARPLOT, +}.freeze
+
+
+ Class Method Summary + collapse +
+ +-
+
+
-
+
+
+ .barplot(*args, width: Barplot::DEFAULT_WIDTH, color: Barplot::DEFAULT_COLOR, symbol: Barplot::DEFAULT_SYMBOL, border: :barplot, xscale: nil, xlabel: nil, data: nil, **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .barplot!(plot, *args, data: nil, **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .boxplot(*args, data: nil, border: :corners, color: Boxplot::DEFAULT_COLOR, width: Boxplot::DEFAULT_WIDTH, xlim: [0, 0], **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .boxplot!(plot, *args, **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .densityplot(x, y, color: :auto, grid: false, name: "", **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .densityplot!(plot, x, y, **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .histogram(x, nbins: nil, closed: :left, symbol: "▇", **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .lineplot(*args, canvas: :braille, color: :auto, name: "", **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .lineplot!(plot, *args, color: :auto, name: "") ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .scatterplot(*args, canvas: :braille, color: :auto, name: "", **kw) ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
-
+
+
+ .scatterplot!(plot, *args, color: :auto, name: "") ⇒ Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ++ +
+
+
+
Class Method Details
+ + ++ + .barplot(*args, width: Barplot::DEFAULT_WIDTH, color: Barplot::DEFAULT_COLOR, symbol: Barplot::DEFAULT_SYMBOL, border: :barplot, xscale: nil, xlabel: nil, data: nil, **kw) ⇒ Object + + + + + +
+ + + +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116+ |
+
+ # File 'src/lib/unicode_plot/barplot.rb', line 79 + +module_function def (*args, + width: Barplot::DEFAULT_WIDTH, + color: Barplot::DEFAULT_COLOR, + symbol: Barplot::DEFAULT_SYMBOL, + border: :barplot, + xscale: nil, + xlabel: nil, + data: nil, + **kw) + case args.length + when 0 + data = Hash(data) + keys = data.keys.map(&:to_s) + heights = data.values + when 2 + keys = Array(args[0]) + heights = Array(args[1]) + else + raise ArgumentError, "invalid arguments" + end + + unless keys.length == heights.length + raise ArgumentError, "The given vectors must be of the same length" + end + unless heights.min >= 0 + raise ArgumentError, "All values have to be positive. Negative bars are not supported." + end + + xlabel ||= ValueTransformer.transform_name(xscale) + plot = Barplot.new(heights, width, color, symbol, xscale, + border: border, xlabel: xlabel, + **kw) + keys.each_with_index do |key, i| + plot.annotate_row!(:l, i, key) + end + + plot +end+ |
+
+ + .barplot!(plot, *args, data: nil, **kw) ⇒ Object + + + + + +
+ + + +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147+ |
+
+ # File 'src/lib/unicode_plot/barplot.rb', line 118 + +module_function def (plot, + *args, + data: nil, + **kw) + case args.length + when 0 + data = Hash(data) + keys = data.keys.map(&:to_s) + heights = data.values + when 2 + keys = Array(args[0]) + heights = Array(args[1]) + else + raise ArgumentError, "invalid arguments" + end + + unless keys.length == heights.length + raise ArgumentError, "The given vectors must be of the same length" + end + if keys.empty? + raise ArgumentError, "Can't append empty array to barplot" + end + + cur_idx = plot.n_rows + plot.add_row!(heights) + keys.each_with_index do |key, i| + plot.annotate_row!(:l, cur_idx + i, key) + end + plot +end+ |
+
+ + .boxplot(*args, data: nil, border: :corners, color: Boxplot::DEFAULT_COLOR, width: Boxplot::DEFAULT_WIDTH, xlim: [0, 0], **kw) ⇒ Object + + + + + +
+ + + +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161+ |
+
+ # File 'src/lib/unicode_plot/boxplot.rb', line 100 + +module_function def boxplot(*args, + data: nil, + border: :corners, + color: Boxplot::DEFAULT_COLOR, + width: Boxplot::DEFAULT_WIDTH, + xlim: [0, 0], + **kw) + case args.length + when 0 + data = Hash(data) + text = data.keys + data = data.values + when 1 + data = args[0] + when 2 + text = Array(args[0]) + data = args[1] + else + raise ArgumentError, "wrong number of arguments" + end + + case data[0] + when Numeric + data = [data] + when Array + # do nothing + else + data = data.to_ary + end + text ||= Array.new(data.length, "") + + unless text.length == data.length + raise ArgumentError, "wrong number of text" + end + + unless xlim.length == 2 + raise ArgumentError, "xlim must be a length 2 array" + end + + min_x, max_x = Utils.extend_limits(data.map(&:minmax).flatten, xlim) + width = [width, Boxplot::MIN_WIDTH].max + + plot = Boxplot.new(data[0], width, color, min_x, max_x, + border: border, **kw) + (1 ... data.length).each do |i| + plot.add_series!(data[i]) + end + + mean_x = (min_x + max_x) / 2.0 + min_x_str = (Utils.roundable?(min_x) ? min_x.round : min_x).to_s + mean_x_str = (Utils.roundable?(mean_x) ? mean_x.round : mean_x).to_s + max_x_str = (Utils.roundable?(max_x) ? max_x.round : max_x).to_s + plot.annotate!(:bl, min_x_str, color: :light_black) + plot.annotate!(:b, mean_x_str, color: :light_black) + plot.annotate!(:br, max_x_str, color: :light_black) + + text.each_with_index do |name, i| + plot.annotate_row!(:l, i*3+1, name) if name.length > 0 + end + + plot +end+ |
+
+ + .boxplot!(plot, *args, **kw) ⇒ Object + + + + + +
+ + + +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194+ |
+
+ # File 'src/lib/unicode_plot/boxplot.rb', line 163 + +module_function def boxplot!(plot, *args, **kw) + case args.length + when 1 + data = args[0] + name = kw[:name] || "" + when 2 + name = args[0] + data = args[1] + else + raise ArgumentError, "worng number of arguments" + end + + if data.empty? + raise ArgumentError, "Can't append empty array to boxplot" + end + + plot.add_series!(data) + + plot.annotate_row!(:l, (plot.n_data - 1)*3+1, name) if name && name != "" + + min_x = plot.min_x + max_x = plot.max_x + mean_x = (min_x + max_x) / 2.0 + min_x_str = (Utils.roundable?(min_x) ? min_x.round : min_x).to_s + mean_x_str = (Utils.roundable?(mean_x) ? mean_x.round : mean_x).to_s + max_x_str = (Utils.roundable?(max_x) ? max_x.round : max_x).to_s + plot.annotate!(:bl, min_x_str, color: :light_black) + plot.annotate!(:b, mean_x_str, color: :light_black) + plot.annotate!(:br, max_x_str, color: :light_black) + + plot +end+ |
+
+ + .densityplot(x, y, color: :auto, grid: false, name: "", **kw) ⇒ Object + + + + + +
+ + + +2 +3 +4 +5+ |
+
+ # File 'src/lib/unicode_plot/densityplot.rb', line 2 + +module_function def densityplot(x, y, color: :auto, grid: false, name: "", **kw) + plot = GridPlot.new(x, y, :density, grid: grid, **kw) + scatterplot!(plot, x, y, color: color, name: name) +end+ |
+
+ + .densityplot!(plot, x, y, **kw) ⇒ Object + + + + + +
+ + + +7 +8 +9+ |
+
+ # File 'src/lib/unicode_plot/densityplot.rb', line 7 + +module_function def densityplot!(plot, x, y, **kw) + scatterplot!(plot, x, y, **kw) +end+ |
+
+ + .histogram(x, nbins: nil, closed: :left, symbol: "▇", **kw) ⇒ Object + + + + + +
+ + + +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47+ |
+
+ # File 'src/lib/unicode_plot/histogram.rb', line 4 + +module_function def histogram(x, + nbins: nil, + closed: :left, + symbol: "▇", + **kw) + hist = x.histogram(*[nbins].compact, closed: closed) + edge, counts = hist.edge, hist.weights + labels = [] + bin_width = edge[1] - edge[0] + pad_left, pad_right = 0, 0 + (0 ... edge.length).each do |i| + val1 = Utils.float_round_log10(edge[i], bin_width) + val2 = Utils.float_round_log10(val1 + bin_width, bin_width) + a1 = val1.to_s.split('.', 2).map(&:length) + a2 = val2.to_s.split('.', 2).map(&:length) + pad_left = [pad_left, a1[0], a2[0]].max + pad_right = [pad_right, a1[1], a2[1]].max + end + l_str = hist.closed == :right ? "(" : "[" + r_str = hist.closed == :right ? "]" : ")" + counts.each_with_index do |n, i| + val1 = Utils.float_round_log10(edge[i], bin_width) + val2 = Utils.float_round_log10(val1 + bin_width, bin_width) + a1 = val1.to_s.split('.', 2).map(&:length) + a2 = val2.to_s.split('.', 2).map(&:length) + labels[i] = "\e[90m#{l_str}\e[0m" + + (" " * (pad_left - a1[0])) + + val1.to_s + + (" " * (pad_right - a1[1])) + + "\e[90m, \e[0m" + + (" " * (pad_left - a2[0])) + + val2.to_s + + (" " * (pad_right - a2[1])) + + "\e[90m#{r_str}\e[0m" + end + xscale = kw.delete(:xscale) + xlabel = kw.delete(:xlabel) || + ValueTransformer.transform_name(xscale, "Frequency") + (labels, counts, + symbol: symbol, + xscale: xscale, + xlabel: xlabel, + **kw) +end+ |
+
+ + .lineplot(*args, canvas: :braille, color: :auto, name: "", **kw) ⇒ Object + + + + + +
+ + + +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42+ |
+
+ # File 'src/lib/unicode_plot/lineplot.rb', line 7 + +module_function def lineplot(*args, + canvas: :braille, + color: :auto, + name: "", + **kw) + case args.length + when 1 + # y only + y = Array(args[0]) + x = Array(1 .. y.length) + when 2 + # x and y + x = Array(args[0]) + y = Array(args[1]) + else + raise ArgumentError, "wrong number of arguments" + end + + case x[0] + when Time, Date + if x[0].is_a? Time + d = x.map(&:to_f) + else + origin = Date.new(1, 1, 1) + d = x.map {|xi| xi - origin } + end + plot = lineplot(d, y, canvas: canvas, color: color, name: name, **kw) + xmin, xmax = x.minmax + plot.annotate!(:bl, xmin.to_s, color: :light_black) + plot.annotate!(:br, xmax.to_s, color: :light_black) + plot + else + plot = Lineplot.new(x, y, canvas, **kw) + lineplot!(plot, x, y, color: color, name: name) + end +end+ |
+
+ + .lineplot!(plot, *args, color: :auto, name: "") ⇒ Object + + + + + +
+ + + +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88+ |
+
+ # File 'src/lib/unicode_plot/lineplot.rb', line 44 + +module_function def lineplot!(plot, + *args, + color: :auto, + name: "") + case args.length + when 1 + # y only + y = Array(args[0]) + x = Array(1 .. y.length) + when 2 + # x and y + x = Array(args[0]) + y = Array(args[1]) + + if x.length == 1 && y.length == 1 + # intercept and slope + intercept = x[0] + slope = y[0] + xmin = plot.origin_x + xmax = plot.origin_x + plot.plot_width + ymin = plot.origin_y + ymax = plot.origin_y + plot.plot_height + x = [xmin, xmax] + y = [intercept + xmin*slope, intercept + xmax*slope] + end + else + raise ArgumentError, "wrong number of arguments" + end + + case x[0] + when Time, Date + if x[0].is_a? Time + d = x.map(&:to_f) + else + origin = Date.new(1, 1, 1) + d = x.map {|xi| xi - origin } + end + lineplot!(plot, d, y, color: color, name: name) + else + color = color == :auto ? plot.next_color : color + plot.annotate!(:r, name.to_s, color: color) unless name.nil? || name == "" + plot.lines!(x, y, color) + end + plot +end+ |
+
+ + .scatterplot(*args, canvas: :braille, color: :auto, name: "", **kw) ⇒ Object + + + + + +
+ + + +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25+ |
+
+ # File 'src/lib/unicode_plot/scatterplot.rb', line 5 + +module_function def scatterplot(*args, + canvas: :braille, + color: :auto, + name: "", + **kw) + case args.length + when 1 + # y only + y = Array(args[0]) + x = Array(1 .. y.length) + when 2 + # x and y + x = Array(args[0]) + y = Array(args[1]) + else + raise ArgumentError, "worng number of arguments" + end + + plot = Scatterplot.new(x, y, canvas, **kw) + scatterplot!(plot, x, y, color: color, name: name) +end+ |
+
+ + .scatterplot!(plot, *args, color: :auto, name: "") ⇒ Object + + + + + +
+ + + +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48+ |
+
+ # File 'src/lib/unicode_plot/scatterplot.rb', line 27 + +module_function def scatterplot!(plot, + *args, + color: :auto, + name: "") + case args.length + when 1 + # y only + y = Array(args[0]) + x = Array(1 .. y.length) + when 2 + # x and y + x = Array(args[0]) + y = Array(args[1]) + else + raise ArgumentError, "worng number of arguments" + end + + color = color == :auto ? plot.next_color : color + plot.annotate!(:r, name.to_s, color: color) unless name.nil? || name == "" + plot.points!(x, y, color) + plot +end+ |
+





