32 Commits

Author SHA1 Message Date
kojix2
e3374c825e v0.3.4 2021-01-21 00:02:30 +09:00
kojix2
c8bdafe9a2 Add encoding test 2021-01-20 23:54:54 +09:00
kojix2
161c85045f -p option changes the meaning from padding to progress 2021-01-20 23:39:17 +09:00
kojix2
3121c43b14 Add some tests 2021-01-20 23:34:14 +09:00
kojix2
c4e6c7ac8c Add some tests 2021-01-20 23:10:10 +09:00
kojix2
edf8849d6a Add test
run_as_executable
2021-01-20 22:30:04 +09:00
kojix2
2e4666f9b4 Improved simple test 2021-01-20 22:21:37 +09:00
kojix2
3bbcea165f Improved error message in barplot 2021-01-20 21:44:08 +09:00
kojix2
3b34ca0e27 Fix a bug 2021-01-20 19:14:58 +09:00
kojix2
abba3e1678 omit count (mac tally) 2021-01-20 00:58:14 +09:00
kojix2
991cf90267 Add test for unrecognized command 2021-01-20 00:57:56 +09:00
kojix2
8db1306e07 Do not exit when using as a library 2021-01-20 00:07:23 +09:00
kojix2
62cc6ba364 Fix style 2021-01-19 23:05:17 +09:00
kojix2
10e096d7c9 Add test count_values_non_tally 2021-01-19 22:37:15 +09:00
kojix2
fbfcf80d25 Add iris-count test 2021-01-19 22:36:36 +09:00
kojix2
8c4011d368 Leave a plot in the terminal on exit. 2021-01-19 20:05:36 +09:00
kojix2
ea4c2a5c70 Hide the cursor in progressive mode 2021-01-19 20:04:29 +09:00
kojix2
c74d54623d Fix option in line 2021-01-19 19:35:31 +09:00
kojix2
b8e7f5af88 Rubocop auto correct 2021-01-19 19:26:41 +09:00
kojix2
a8ce96888e Fix xlim and ylim 2021-01-19 19:23:44 +09:00
kojix2
c9513e463f Add grid to parser 2021-01-19 19:04:08 +09:00
kojix2
b2f2c16c59 Fix style 2021-01-19 18:09:09 +09:00
kojix2
93195713e6 Refactoring of sub_parser 2021-01-19 17:34:18 +09:00
kojix2
2e7a7c8851 Fix canvas option 2021-01-19 16:16:21 +09:00
kojix2
8d6d9158f2 Fix options desc 2021-01-19 16:16:03 +09:00
kojix2
774fa88872 Fix indentation again 2021-01-19 16:00:29 +09:00
kojix2
001434a507 Improved the description of option value types 2021-01-19 15:49:16 +09:00
kojix2
08b946fb7e Fix typo 2021-01-19 15:48:25 +09:00
kojix2
9fcb647aa5 Improve hist closed options desc 2021-01-19 15:14:57 +09:00
kojix2
68101d31cb Fix indentation in the here document 2021-01-19 14:56:28 +09:00
kojix2
dbbff1dc3a Improve bar xscale option 2021-01-19 14:55:28 +09:00
kojix2
e8923dc876 Add acknowledgements to README.md 2021-01-13 18:41:18 +09:00
32 changed files with 750 additions and 262 deletions

View File

@@ -201,7 +201,7 @@ Usage: uplot histogram [options] <in.tsv>
Options for histogram:
--symbol VAL character to be used to plot the bars
--closed VAL
--closed VAL side of the intervals to be closed [left]
-n, --nbins VAL approximate number of bins
Options:
@@ -233,6 +233,12 @@ bundle exec rake test # Run the test
bundle exec rake install # Installation from source code
```
### Acknowledgements
* [Red Data Tools](https://github.com/red-data-tools) - Technical support
* [sampo grafiikka](https://jypg.net/sampo_grafiikka) - Project logo creation
* [yutaas](https://github.com/yutaas) - English proofreading
## License
[MIT License](https://opensource.org/licenses/MIT).

View File

@@ -3,4 +3,4 @@
require 'youplot'
YouPlot::Command.new.run
YouPlot::Command.new.run_as_executable

View File

@@ -3,4 +3,4 @@
require 'youplot'
YouPlot::Command.new.run
YouPlot::Command.new.run_as_executable

View File

@@ -6,4 +6,12 @@ require 'youplot/dsv'
require 'youplot/command'
module YouPlot
class << self
attr_accessor :run_as_executable
def run_as_executable?
@run_as_executable
end
end
@run_as_executable = false
end

View File

@@ -6,9 +6,9 @@ module YouPlot
module Processing
module_function
def count_values(arr)
def count_values(arr, tally: true)
# tally was added in Ruby 2.7
if Enumerable.method_defined? :tally
if tally && Enumerable.method_defined?(:tally)
arr.tally
else
# https://github.com/marcandre/backports

View File

@@ -7,6 +7,8 @@ module YouPlot
# plotting functions.
module Backends
module UnicodePlotBackend
class Error < StandardError; end
module_function
def barplot(data, params, fmt = nil, count: false)
@@ -37,7 +39,19 @@ module YouPlot
labels = series[x_col]
values = series[y_col].map(&:to_f)
end
UnicodePlot.barplot(labels, values, **params.to_hc)
begin
UnicodePlot.barplot(labels, values, **params.to_hc)
# UnicodePlot error:
# All values have to be positive. Negative bars are not supported.
rescue ArgumentError => e
if YouPlot.run_as_executable?
warn e.backtrace[0]
warn "\e[35m#{e}\e[0m"
exit 1
else
raise e
end
end
end
def histogram(data, params)
@@ -90,6 +104,7 @@ module YouPlot
params.name ||= headers[1]
params.xlabel ||= headers[0]
end
params.xlim ||= series[0].flatten.minmax # why need?
params.ylim ||= series[1..-1].flatten.minmax # why need?
plot = UnicodePlot.public_send(method1, series[0], series[1], **params.to_hc)
2.upto(series.size - 1) do |i|
@@ -103,13 +118,14 @@ module YouPlot
series = data.series
method2 = get_method2(method1)
series.map! { |s| s.map(&:to_f) }
series = series.each_slice(2).to_a
series2 = series.each_slice(2).to_a
series = nil
params.name ||= headers[0] if headers
params.xlim = series.map(&:first).flatten.minmax # why need?
params.ylim = series.map(&:last).flatten.minmax # why need?
x1, y1 = series.shift
params.xlim ||= series2.map(&:first).flatten.minmax # why need?
params.ylim ||= series2.map(&:last).flatten.minmax # why need?
x1, y1 = series2.shift
plot = UnicodePlot.public_send(method1, x1, y1, **params.to_hc)
series.each_with_index do |(xi, yi), i|
series2.each_with_index do |(xi, yi), i|
UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
end
plot
@@ -179,14 +195,14 @@ module YouPlot
warn " Headers: \e[35m#{data.headers.inspect}\e[0m"
warn " The first item is: \e[35m\"#{series[0][0]}\"\e[0m"
warn " The last item is : \e[35m\"#{series[0][-1]}\"\e[0m"
exit 1
YouPlot.run_as_executable ? exit(1) : raise(Error)
end
if fmt == 'xyxy' && series.size.odd?
warn 'YouPlot: In the xyxy format, the number of series must be even.'
warn ''
warn " Number of series: \e[35m#{series.size}\e[0m"
warn " Headers: \e[35m#{data.headers.inspect}\e[0m"
exit 1
YouPlot.run_as_executable ? exit(1) : raise(Error)
end
end
end

View File

@@ -22,6 +22,11 @@ module YouPlot
@backend = YouPlot::Backends::UnicodePlotBackend
end
def run_as_executable
YouPlot.run_as_executable = true
run
end
def run
parser.parse_options(@argv)
@command ||= parser.command
@@ -34,11 +39,15 @@ module YouPlot
elsif options[:progressive]
stop = false
Signal.trap(:INT) { stop = true }
options[:output].print "\e[?25l" # make cursor invisible
while (input = Kernel.gets)
main_progressive(input)
n = main_progressive(input)
break if stop
options[:output].print "\e[#{n}F"
end
options[:output].print "\e[0J"
options[:output].print "\e[?25h" # make cursor visible
else
# Sometimes the input file does not end with a newline code.
while (input = Kernel.gets(nil))
@@ -154,8 +163,7 @@ module YouPlot
end
options[:output].print "\e[0J"
options[:output].flush
n = out.string.lines.size
options[:output].print "\e[#{n}F"
out.string.lines.size
else
raise 'In progressive mode, output to a file is not possible.'
end

View File

@@ -7,7 +7,10 @@ require_relative 'plot_params'
module YouPlot
class Command
class Parser
attr_reader :command, :options, :params
class Error < StandardError; end
attr_reader :command, :options, :params,
:main_parser, :sub_parser
def initialize
@command = nil
@@ -28,257 +31,265 @@ module YouPlot
end
def create_default_parser
OptionParser.new do |opt|
opt.program_name = 'YouPlot'
opt.version = YouPlot::VERSION
opt.summary_width = 24
opt.on_tail('') # Add a blank line at the end
opt.separator('')
opt.on('Common options:')
opt.on('-O', '--pass [FILE]', 'file to output input data to [stdout]',
'for inserting YouPlot in the middle of Unix pipes') do |v|
@options[:pass] = v || $stdout
OptionParser.new do |parser|
parser.program_name = 'YouPlot'
parser.version = YouPlot::VERSION
parser.summary_width = 24
parser.on_tail('') # Add a blank line at the end
parser.separator('')
parser.on('Common options:')
parser.on('-O', '--pass [FILE]', 'file to output input data to [stdout]',
'for inserting YouPlot in the middle of Unix pipes') do |v|
options[:pass] = v || $stdout
end
opt.on('-o', '--output [FILE]', 'file to output plots to [stdout]',
'If no option is specified, plot will print to stderr') do |v|
@options[:output] = v || $stdout
parser.on('-o', '--output [FILE]', 'file to output plots to [stdout]',
'If no option is specified, plot will print to stderr') do |v|
options[:output] = v || $stdout
end
opt.on('-d', '--delimiter VAL', String, 'use DELIM instead of TAB for field delimiter') do |v|
@options[:delimiter] = v
parser.on('-d', '--delimiter DELIM', String, 'use DELIM instead of [TAB] for field delimiter') do |v|
options[:delimiter] = v
end
opt.on('-H', '--headers', TrueClass, 'specify that the input has header row') do |v|
@options[:headers] = v
parser.on('-H', '--headers', TrueClass, 'specify that the input has header row') do |v|
options[:headers] = v
end
opt.on('-T', '--transpose', TrueClass, 'transpose the axes of the input data') do |v|
@options[:transpose] = v
parser.on('-T', '--transpose', TrueClass, 'transpose the axes of the input data') do |v|
options[:transpose] = v
end
opt.on('-t', '--title VAL', String, 'print string on the top of plot') do |v|
parser.on('-t', '--title STR', String, 'print string on the top of plot') do |v|
params.title = v
end
opt.on('-x', '--xlabel VAL', String, 'print string on the bottom of the plot') do |v|
parser.on('-x', '--xlabel STR', String, 'print string on the bottom of the plot') do |v|
params.xlabel = v
end
opt.on('-y', '--ylabel VAL', String, 'print string on the far left of the plot') do |v|
parser.on('-y', '--ylabel STR', String, 'print string on the far left of the plot') do |v|
params.ylabel = v
end
opt.on('-w', '--width VAL', Integer, 'number of characters per row') do |v|
parser.on('-w', '--width INT', Integer, 'number of characters per row') do |v|
params.width = v
end
opt.on('-h', '--height VAL', Numeric, 'number of rows') do |v|
parser.on('-h', '--height INT', Numeric, 'number of rows') do |v|
params.height = v
end
opt.on('-b', '--border VAL', String, 'specify the style of the bounding box') do |v|
parser.on('-b', '--border STR', String, 'specify the style of the bounding box') do |v|
params.border = v.to_sym
end
opt.on('-m', '--margin VAL', Numeric, 'number of spaces to the left of the plot') do |v|
parser.on('-m', '--margin INT', Numeric, 'number of spaces to the left of the plot') do |v|
params.margin = v
end
opt.on('-p', '--padding VAL', Numeric, 'space of the left and right of the plot') do |v|
parser.on('--padding INT', Numeric, 'space of the left and right of the plot') do |v|
params.padding = v
end
opt.on('-c', '--color VAL', String, 'color of the drawing') do |v|
parser.on('-c', '--color VAL', String, 'color of the drawing') do |v|
params.color = v =~ /\A[0-9]+\z/ ? v.to_i : v.to_sym
end
opt.on('--[no-]labels', TrueClass, 'hide the labels') do |v|
parser.on('--[no-]labels', TrueClass, 'hide the labels') do |v|
params.labels = v
end
opt.on('--progress', TrueClass, 'progressive mode [experimental]') do |v|
@options[:progressive] = v
parser.on('-p', '--progress', TrueClass, 'progressive mode [experimental]') do |v|
options[:progressive] = v
end
opt.on('--encoding VAL', String, 'Specify the input encoding') do |v|
@options[:encoding] = v
parser.on('--encoding STR', String, 'Specify the input encoding') do |v|
options[:encoding] = v
end
# Optparse adds the help option, but it doesn't show up in usage.
# This is why you need the code below.
opt.on('--help', 'print sub-command help menu') do
puts opt.help
exit
parser.on('--help', 'print sub-command help menu') do
puts parser.help
exit if YouPlot.run_as_executable?
end
opt.on('--debug', TrueClass, 'print preprocessed data') do |v|
@options[:debug] = v
parser.on('--debug', TrueClass, 'print preprocessed data') do |v|
options[:debug] = v
end
yield opt if block_given?
# yield opt if block_given?
end
end
def main_parser
@main_parser ||= create_default_parser do |main_parser|
# Here, help message is stored in the banner.
# Because help of main_parser may be referred by `sub_parser`.
main_parser.banner = \
<<~MSG
Program: YouPlot (Tools for plotting on the terminal)
Version: #{YouPlot::VERSION} (using UnicodePlot #{UnicodePlot::VERSION})
Source: https://github.com/kojix2/youplot
def create_main_parser
@main_parser = create_default_parser
main_parser.banner = \
<<~MSG
Usage: uplot <command> [options] <in.tsv>
Program: YouPlot (Tools for plotting on the terminal)
Version: #{YouPlot::VERSION} (using UnicodePlot #{UnicodePlot::VERSION})
Source: https://github.com/kojix2/youplot
Commands:
barplot bar draw a horizontal barplot
histogram hist draw a horizontal histogram
lineplot line draw a line chart
lineplots lines draw a line chart with multiple series
scatter s draw a scatter plot
density d draw a density plot
boxplot box draw a horizontal boxplot
colors color show the list of available colors
Usage: uplot <command> [options] <in.tsv>
count c draw a baplot based on the number of
occurrences (slow)
General options:
--help print command specific help menu
--version print the version of YouPlot
MSG
Commands:
barplot bar draw a horizontal barplot
histogram hist draw a horizontal histogram
lineplot line draw a line chart
lineplots lines draw a line chart with multiple series
scatter s draw a scatter plot
density d draw a density plot
boxplot box draw a horizontal boxplot
colors color show the list of available colors
# Actually, main_parser can take common optional arguments.
# However, these options dose not be shown in the help menu.
# I think the main help should be simple.
main_parser.on('--help', 'print sub-command help menu') do
puts main_parser.banner
puts
exit
end
count c draw a baplot based on the number of
occurrences (slow)
General options:
--help print command specific help menu
--version print the version of YouPlot
MSG
# Help for the main parser is simple.
# Simply show the banner above.
main_parser.on('--help', 'print sub-command help menu') do
puts main_parser.banner
puts
exit if YouPlot.run_as_executable?
end
end
def sub_parser
@sub_parser ||= create_default_parser do |parser|
parser.banner = <<~MSG
def sub_parser_add_symbol
sub_parser.on_head('--symbol STR', String, 'character to be used to plot the bars') do |v|
params.symbol = v
end
end
def sub_parser_add_xscale
xscale_options = UnicodePlot::ValueTransformer::PREDEFINED_TRANSFORM_FUNCTIONS.keys.join(', ')
sub_parser.on_head('--xscale STR', String, "axis scaling (#{xscale_options})") do |v|
params.xscale = v
end
end
def sub_parser_add_canvas
sub_parser.on_head('--canvas STR', String, 'type of canvas') do |v|
params.canvas = v.to_sym
end
end
def sub_parser_add_xlim
sub_parser.on_head('--xlim FLOAT,FLOAT', Array, 'plotting range for the x coordinate') do |v|
params.xlim = v.take(2)
end
end
def sub_parser_add_ylim
sub_parser.on_head('--ylim FLOAT,FLOAT', Array, 'plotting range for the y coordinate') do |v|
params.ylim = v.take(2)
end
end
def sub_parser_add_grid
sub_parser.on_head('--[no-]grid', TrueClass, 'draws grid-lines at the origin') do |v|
params.grid = v
end
end
def create_sub_parser
@sub_parser = create_default_parser
sub_parser.banner = \
<<~MSG
Usage: YouPlot #{command} [options] <in.tsv>
Options for #{command}:
MSG
case command
case command
# If you type only `uplot` in the terminal.
when nil
warn main_parser.banner
warn "\n"
# If you type only `uplot` in the terminal.
when nil
warn main_parser.banner
warn "\n"
exit 1 if YouPlot.run_as_executable?
when :barplot, :bar
sub_parser_add_symbol
sub_parser.on_head('--fmt STR', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v|
options[:fmt] = v
end
sub_parser_add_xscale
when :count, :c
sub_parser_add_symbol
sub_parser_add_xscale
when :histogram, :hist
sub_parser_add_symbol
sub_parser.on_head('--closed STR', String, 'side of the intervals to be closed [left]') do |v|
params.closed = v
end
sub_parser.on_head('-n', '--nbins INT', Numeric, 'approximate number of bins') do |v|
params.nbins = v
end
when :lineplot, :line
sub_parser_add_canvas
sub_parser_add_grid
sub_parser.on_head('--fmt STR', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v|
options[:fmt] = v
end
sub_parser_add_ylim
sub_parser_add_xlim
when :lineplots, :lines
sub_parser_add_canvas
sub_parser_add_grid
sub_parser.on_head('--fmt STR', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...',
'xyy : header is like x, y1, y2, y2, y3...') do |v|
options[:fmt] = v
end
sub_parser_add_ylim
sub_parser_add_xlim
when :scatter, :s
sub_parser_add_canvas
sub_parser_add_grid
sub_parser.on_head('--fmt STR', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...',
'xyy : header is like x, y1, y2, y2, y3...') do |v|
options[:fmt] = v
end
sub_parser_add_ylim
sub_parser_add_xlim
when :density, :d
sub_parser_add_canvas
sub_parser_add_grid
sub_parser.on('--fmt STR', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...',
'xyy : header is like x, y1, y2, y2, y3...') do |v|
options[:fmt] = v
end
sub_parser_add_ylim
sub_parser_add_xlim
when :boxplot, :box
sub_parser_add_xlim
when :colors, :color, :colours, :colour
sub_parser.on_head('-n', '--names', 'show color names only', TrueClass) do |v|
options[:color_names] = v
end
else
error_message = "uplot: unrecognized command '#{command}'"
if YouPlot.run_as_executable?
warn error_message
exit 1
when :barplot, :bar
parser.on_head('--symbol VAL', String, 'character to be used to plot the bars') do |v|
params.symbol = v
end
parser.on_head('--xscale VAL', String, 'axis scaling') do |v|
params.xscale = v
end
parser.on_head('--fmt VAL', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v|
@options[:fmt] = v
end
when :count, :c
parser.on_head('--symbol VAL', String, 'character to be used to plot the bars') do |v|
params.symbol = v
end
when :histogram, :hist
parser.on_head('-n', '--nbins VAL', Numeric, 'approximate number of bins') do |v|
params.nbins = v
end
parser.on_head('--closed VAL', String) do |v|
params.closed = v
end
parser.on_head('--symbol VAL', String, 'character to be used to plot the bars') do |v|
params.symbol = v
end
when :lineplot, :line
parser.on_head('--canvas VAL', String, 'type of canvas') do |v|
params.canvas = v
end
parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
params.xlim = v.take(2)
end
parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
params.ylim = v.take(2)
end
parser.on_head('--fmt VAL', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v|
@options[:fmt] = v
end
when :lineplots, :lines
parser.on_head('--canvas VAL', String) do |v|
params.canvas = v
end
parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
params.xlim = v.take(2)
end
parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
params.ylim = v.take(2)
end
parser.on_head('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...',
'xyy : header is like x, y1, y2, y2, y3...') do |v|
@options[:fmt] = v
end
when :scatter, :s
parser.on_head('--canvas VAL', String) do |v|
params.canvas = v
end
parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
params.xlim = v.take(2)
end
parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
params.ylim = v.take(2)
end
parser.on_head('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...',
'xyy : header is like x, y1, y2, y2, y3...') do |v|
@options[:fmt] = v
end
when :density, :d
parser.on_head('--grid', TrueClass) do |v|
params.grid = v
end
parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
params.xlim = v.take(2)
end
parser.on_head('--ylim VAL', Array, 'plotting range for the y coordinate') do |v|
params.ylim = v.take(2)
end
parser.on('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...',
'xyy : header is like x, y1, y2, y2, y3...') do |v|
@options[:fmt] = v
end
when :boxplot, :box
parser.on_head('--xlim VAL', Array, 'plotting range for the x coordinate') do |v|
params.xlim = v.take(2)
end
when :colors, :color, :colours, :colour
parser.on_head('-n', '--names', 'show color names only', TrueClass) do |v|
@options[:color_names] = v
end
else
warn "uplot: unrecognized command '#{command}'"
exit 1
raise Error, error_message
end
end
end
def parse_options(argv = ARGV)
begin
main_parser.order!(argv)
create_main_parser.order!(argv)
rescue OptionParser::ParseError => e
warn "uplot: #{e.message}"
exit 1
exit 1 if YouPlot.run_as_executable?
end
@command = argv.shift&.to_sym
begin
sub_parser.parse!(argv)
create_sub_parser&.parse!(argv)
rescue OptionParser::ParseError => e
warn "uplot: #{e.message}"
exit 1
exit 1 if YouPlot.run_as_executable?
end
end
end

View File

@@ -25,10 +25,10 @@ module YouPlot
Data.new(headers, series)
elsif h_size > s_size
warn "\e[35mThe number of headers is greater than the number of series.\e[0m"
exit 1
exit 1 if YouPlot.run_as_executable?
elsif h_size < s_size
warn "\e[35mThe number of headers is less than the number of series.\e[0m"
exit 1
exit 1 if YouPlot.run_as_executable?
end
end
end
@@ -67,12 +67,10 @@ module YouPlot
else
Array.new(arr[0].size, [])
end
elsif transpose
arr
else
if transpose
arr
else
transpose2(arr)
end
transpose2(arr)
end
end
end

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true
module YouPlot
VERSION = '0.3.3'
VERSION = '0.3.4'
end

38
test/fixtures/iris-count.txt vendored Normal file
View File

@@ -0,0 +1,38 @@
sepal_length
┌ ┐
5.0 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 10.0
6.3 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 9.0
5.1 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 9.0
6.7 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■ 8.0
5.7 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■ 8.0
6.4 ┤■■■■■■■■■■■■■■■■■■■■■■■■ 7.0
5.5 ┤■■■■■■■■■■■■■■■■■■■■■■■■ 7.0
5.8 ┤■■■■■■■■■■■■■■■■■■■■■■■■ 7.0
5.6 ┤■■■■■■■■■■■■■■■■■■■■ 6.0
6.1 ┤■■■■■■■■■■■■■■■■■■■■ 6.0
6.0 ┤■■■■■■■■■■■■■■■■■■■■ 6.0
5.4 ┤■■■■■■■■■■■■■■■■■■■■ 6.0
4.9 ┤■■■■■■■■■■■■■■■■■■■■ 6.0
6.5 ┤■■■■■■■■■■■■■■■■■ 5.0
4.8 ┤■■■■■■■■■■■■■■■■■ 5.0
7.7 ┤■■■■■■■■■■■■■■ 4.0
6.2 ┤■■■■■■■■■■■■■■ 4.0
6.9 ┤■■■■■■■■■■■■■■ 4.0
5.2 ┤■■■■■■■■■■■■■■ 4.0
4.6 ┤■■■■■■■■■■■■■■ 4.0
7.2 ┤■■■■■■■■■■ 3.0
6.8 ┤■■■■■■■■■■ 3.0
5.9 ┤■■■■■■■■■■ 3.0
4.4 ┤■■■■■■■■■■ 3.0
6.6 ┤■■■■■■■ 2.0
4.7 ┤■■■■■■■ 2.0
7.9 ┤■■■ 1.0
7.4 ┤■■■ 1.0
7.3 ┤■■■ 1.0
7.6 ┤■■■ 1.0
7.1 ┤■■■ 1.0
7.0 ┤■■■ 1.0
5.3 ┤■■■ 1.0
4.5 ┤■■■ 1.0
4.3 ┤■■■ 1.0
└ ┘

View File

@@ -1,20 +1,20 @@
IRIS-DENSITY
┌────────────────────────────────────────┐
6.9 │ │ sepal_width
6.9 │ │ sepal_width
│ │ petal_length
│ petal_width
│ species
░ │
│ │
│ petal_width
░░ │ species
│ ░
│ ░ │
░░ ░
░ ░ ░
░░
▒░
░░ ░░ ░ ░ ░░ ░░░
│ ░ ░ ░ ░ │
│ ░░ ░ ░ │
│ ░ ░░░▒ ░ ░ ░░░ ░ ░ │
│ ░ ░░░░ │
│ │
░ ░▒ ░ ░ ░ ░
│ ░ ░ ░ │
│ │
0 │ ░░ ▒ ░█ ░ ░▒ ░░ ░ ░░░ ░ │
0 │ ░ ░▒▒██ ▒ ▓▒░▒▒░░░ ░▒▒░ ▒░░
└────────────────────────────────────────┘
4 8
4.3 7.9
sepal_length

View File

@@ -1,20 +1,20 @@
IRIS-LINEPLOTS
┌────────────────────────────────────────┐
6.9 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣲⠭⠃⠀⠀│ sepal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⢀⣀⣠⣤⣶⣿⣿⣯⣴⣒⠖⠉⠁│ petal_length
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⢮⣤⣤⣶⣿⣿⣿⠿⠛⠛⠋⠉⠀⠀⠀⠀⠀⠀│ petal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣴⣷⣿⣿⣿⣿⣿⣿⣟⣟⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ species
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠤⠔⠒⢙⡻⠝⢋⡽⢝⣳⣾⣫⣥⣒⣪⣵⣖⣂⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠀⠀⢀⣉⣟⣻⣿⣻⣿⣿⣿⠿⣿⣿⠿⠟⡢⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⣠⣤⣿⣷⣾⣿⡿⣿⡯⠿⠛⠋⠉⣀⠔⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣄⣀⠄
│⠀⠀⠀⠀⢀⣨⣽⣿⣿⣿⣿⣿⣿⣿⣵⣚⣉⣃⣀⣠⣤⣤⣔⣮⣤⣄⣀⣤⣔⣾⡳⠮⠛⠋⢉⡗⠁⠀│
⠀⠀⠐⠒⡿⠿⠟⡻⠛⠛⠛⠚⠉⠀⠲⣶⣿⣷⣾⣷⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣷⠀⠀│
│⠀⠀⠀⠀⢱⡠⠊⠀⠀⣤⣤⣶⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣟⣟⣉⣉⣝⣛⣫⣭⣥⣤⣤⣔⣒⣒⠀⠀│
│⠀⠀⠀⠀⠀⠁⠀⢀⡀⠀⢯⠒⠉⡠⠔⠡⠤⠮⣤⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣿⣿⠥⠤⠄
│⠀⠀⠀⠀⣀⣠⣄⣤⣭⣿⣿⣿⣿⣿⣿⣿⣿⣯⣯⣯⣭⣿⣿⣿⣿⣿⣯⣭⣍⡙⠛⠝⠉⠀⠀⠀⠀⠀⠀│
⠀⠀⠠⠴⠿⢯⠭⠿⠯⣭⣷⡾⠿⠿⠿⣿⢿⡿⡻⠿⡟⠛⢛⣛⠯⠭⠒⠒⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣄⠀⠀⠀⢀⣀⡠⠤⠔⠒⠊⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
0 │⠀⠀⢀⣀⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣷⣄⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀
6.9 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⡮⠟⠀⠀│ sepal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⣀⣀⣤⣴⣶⣿⣟⣯⣥⣔⣲⠊⠉│ petal_length
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣔⢾⣥⣤⣶⣿⣿⣿⠿⠛⠛⠋⠉⠀⠀⠀⠀⠀⠀│ petal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣛⣗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ species
│⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠔⠒⣋⡻⠭⠛⣩⡿⣟⣷⣽⣫⣥⣒⣲⣭⣶⣒⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠈⠉⢀⣉⡟⣛⣿⣝⣻⣿⣿⣿⠿⢿⣿⡿⠿⣛⠤⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⣠⣤⣿⣷⣿⣿⣿⣿⣿⠿⠿⠛⠋⠉⣀⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⢀⣠
│⠀⢀⣀⣭⣿⣿⣿⣿⣿⣿⣿⣿⣽⣖⣋⣙⣀⣀⣤⣤⣤⣔⣮⣤⣄⣀⣀⣤⣤⣔⣾⡳⠮⠝⠓⢊⢽⠋⠀│
⠒⢷⠿⠿⢛⠟⠛⠙⠑⠚⠉⠀⠲⣶⣿⣿⣶⣿⣷⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣷⠀⠀│
│⠀⠸⡠⠔⠁⠀⢠⡤⣴⣶⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣟⣟⣉⣉⣩⣛⣛⣭⣭⣥⣤⣤⣔⣒⣒⠀⠀│
│⠀⠀⠁⠀⠀⢀⡀⠨⢞⠊⢉⡠⠔⠉⠤⠴⢥⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣿⣿⡭⠤⠤
│⠀⣀⣀⣄⣤⣤⣽⣿⣿⣿⣿⣿⣿⡿⣿⣿⣽⣽⣯⣭⣿⣿⣿⣿⣿⣿⣿⣭⣭⣉⠛⠛⠝⠉⠀⠀⠀⠀⠀⠀│
⠤⠿⠿⡯⠽⠿⢭⣽⣶⡾⠿⠿⠿⣿⠿⣿⢟⠿⢻⠟⠛⣛⣛⠯⠭⠝⠒⠊⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⢀⣀⡠⣀⠀⠀⠀⢀⣀⡠⠤⠤⠒⠒⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
0 │⣀⣴⣶⣾⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀│
└────────────────────────────────────────┘
4 8
4.3 7.9
sepal_length

View File

@@ -1,20 +1,20 @@
IRIS-SCATTER
┌────────────────────────────────────────┐
6.9 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠃⠀⠀│ sepal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠂⠄⠀⠀⠄⠀⠁│ petal_length
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⡀⡀⠂⠀⡆⠁⠄⠈⠀⠂⠀⠀⠀⠀⠀⠀⠀│ petal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⡀⡀⠀⠂⡀⠃⡅⠀⠄⠁⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ species
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠁⠀⠄⢕⠀⠄⡃⠀⠀⠀⡁⠄⠂⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠁⣊⠀⡃⠀⡀⠉⠀⠅⠂⠅⠙⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠀⢅⠀⡄⡮⠀⠅⠇⠀⠒⠄⠀⠄
│⠀⠀⠀⠀⠀⠨⠀⠠⠀⡀⣷⠀⠆⠀⠄⠊⠀⠂⠀⠀⠄⠀⠄⡄⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀│
⠀⠀⠐⠀⠇⠘⠀⠑⠀⠂⠓⠀⠀⠀⠂⠀⡆⡀⠃⢶⠀⡄⡄⡇⡳⠀⠂⡃⠃⠑⠀⠃⠄⡀⠀⠂⡂⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠠⠀⠁⠀⠀⡮⠀⠆⡃⠀⠑⠀⠀⡅⠁⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠁⠀⢀⠀⠀⢅⠀⠀⠀⠀⠡⠀⠄⡀⠀⠁⠀⠁⡁⡃⠅⠀⠃⠃⠃⠐⠀⠀⠀⡀⠀⠂⠅⠀⠄
│⠀⠀⠀⠀⡀⢠⠀⢤⠀⡆⣴⠀⡤⠀⠆⡠⠀⠆⠀⠅⢍⠀⠅⠅⠅⢅⠀⡇⡀⠄⡀⠀⠅⠁⠀⠀⠀⠀⠀⠀│
⠀⠀⠠⠀⠁⢁⠀⠁⠀⡀⡣⠀⠀⠀⠁⡯⠀⡃⡂⠀⡘⠀⠁⠁⠁⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
0 │⠀⠀⢀⠀⡄⣲⠀⣴⠀⡄⣿⠀⣤⠀⡅⣄⠀⡃⡄⡀⣀⠀⡀⡀⡀⣀⠀⡀⡀⡀⣀⠀⡀⡀⡀⠀⡀⡀⠀⡀
6.9 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠘⠀⠀│ sepal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠂⠄⠀⠀⠠⠀⠈│ petal_length
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⡀⡀⠂⠀⢰⠈⠠⠀⠀⠁⠂⠀⠀⠀⠀⠀⠀⠀│ petal_width
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢀⢀⠀⠀⠂⡀⠃⡅⠀⠠⠈⢐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│ species
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠈⠀⠠⠨⢐⠀⠄⡃⠀⠀⠀⢈⠠⠐⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⡂⡁⢘⠀⢀⠈⠈⠀⠅⠂⠅⠁⠘⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⢠⠀⠅⡀⡄⡆⠅⠨⠸⠀⠐⠐⠀⠠⠀⠠
│⠀⠀⠀⠅⠀⠠⢀⢸⢰⠀⠆⠀⠄⠂⠁⠐⠀⠀⠠⠀⠀⠄⡄⠀⠀⠀⢀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀│
⠂⠇⠀⠃⠁⠐⠐⠘⠐⠀⠀⠀⠂⠀⡆⢰⢀⠘⠰⢰⠀⡄⡄⡇⡃⠰⠐⢘⠘⠈⠀⠂⠃⠄⡀⠀⠐⢐⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠠⠀⠁⠀⠀⡆⠅⠰⢘⠀⠈⠐⠀⠀⡅⠁⠀⠀⢠⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀│
│⠀⠀⠁⠀⠀⢀⠀⠨⢀⠀⠀⠀⠀⠁⠄⠠⢀⠀⠈⠀⠀⠁⡁⡃⠅⠀⠘⠘⠘⠀⠀⠂⠀⠀⡀⠀⠐⠨⠀⠠
│⠀⡀⠀⡄⠄⢠⢰⢠⢰⠀⡄⠄⠆⡀⠄⠰⠀⠨⠨⢈⠀⠅⠅⠅⠅⢀⢸⢀⠠⢀⠀⠀⠅⠁⠀⠀⠀⠀⠀⠀│
⠄⠁⠁⡀⠁⠀⢀⢘⠠⠀⠀⠀⠁⡇⠅⢘⢐⠀⢀⠘⠀⠁⠁⠁⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠠⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
0 │⡀⡄⡂⡆⡄⢰⢠⢸⢸⠀⡄⡄⡅⡄⡀⢘⢠⢀⢀⢀⠀⡀⡀⡀⡀⢀⢀⢀⢀⢀⠀⡀⡀⡀⡀⠀⢀⢀⠀⢀
└────────────────────────────────────────┘
4 8
4.3 7.9
sepal_length

BIN
test/fixtures/iris_utf16.csv vendored Normal file

Binary file not shown.
1 sepal_length sepal_width petal_length petal_width species
2 5.1 3.5 1.4 0.2 Iris-setosa
3 4.9 3.0 1.4 0.2 Iris-setosa
4 4.7 3.2 1.3 0.2 Iris-setosa
5 4.6 3.1 1.5 0.2 Iris-setosa
6 5.0 3.6 1.4 0.2 Iris-setosa
7 5.4 3.9 1.7 0.4 Iris-setosa
8 4.6 3.4 1.4 0.3 Iris-setosa
9 5.0 3.4 1.5 0.2 Iris-setosa
10 4.4 2.9 1.4 0.2 Iris-setosa
11 4.9 3.1 1.5 0.1 Iris-setosa
12 5.4 3.7 1.5 0.2 Iris-setosa
13 4.8 3.4 1.6 0.2 Iris-setosa
14 4.8 3.0 1.4 0.1 Iris-setosa
15 4.3 3.0 1.1 0.1 Iris-setosa
16 5.8 4.0 1.2 0.2 Iris-setosa
17 5.7 4.4 1.5 0.4 Iris-setosa
18 5.4 3.9 1.3 0.4 Iris-setosa
19 5.1 3.5 1.4 0.3 Iris-setosa
20 5.7 3.8 1.7 0.3 Iris-setosa
21 5.1 3.8 1.5 0.3 Iris-setosa
22 5.4 3.4 1.7 0.2 Iris-setosa
23 5.1 3.7 1.5 0.4 Iris-setosa
24 4.6 3.6 1.0 0.2 Iris-setosa
25 5.1 3.3 1.7 0.5 Iris-setosa
26 4.8 3.4 1.9 0.2 Iris-setosa
27 5.0 3.0 1.6 0.2 Iris-setosa
28 5.0 3.4 1.6 0.4 Iris-setosa
29 5.2 3.5 1.5 0.2 Iris-setosa
30 5.2 3.4 1.4 0.2 Iris-setosa
31 4.7 3.2 1.6 0.2 Iris-setosa
32 4.8 3.1 1.6 0.2 Iris-setosa
33 5.4 3.4 1.5 0.4 Iris-setosa
34 5.2 4.1 1.5 0.1 Iris-setosa
35 5.5 4.2 1.4 0.2 Iris-setosa
36 4.9 3.1 1.5 0.1 Iris-setosa
37 5.0 3.2 1.2 0.2 Iris-setosa
38 5.5 3.5 1.3 0.2 Iris-setosa
39 4.9 3.1 1.5 0.1 Iris-setosa
40 4.4 3.0 1.3 0.2 Iris-setosa
41 5.1 3.4 1.5 0.2 Iris-setosa
42 5.0 3.5 1.3 0.3 Iris-setosa
43 4.5 2.3 1.3 0.3 Iris-setosa
44 4.4 3.2 1.3 0.2 Iris-setosa
45 5.0 3.5 1.6 0.6 Iris-setosa
46 5.1 3.8 1.9 0.4 Iris-setosa
47 4.8 3.0 1.4 0.3 Iris-setosa
48 5.1 3.8 1.6 0.2 Iris-setosa
49 4.6 3.2 1.4 0.2 Iris-setosa
50 5.3 3.7 1.5 0.2 Iris-setosa
51 5.0 3.3 1.4 0.2 Iris-setosa
52 7.0 3.2 4.7 1.4 Iris-versicolor
53 6.4 3.2 4.5 1.5 Iris-versicolor
54 6.9 3.1 4.9 1.5 Iris-versicolor
55 5.5 2.3 4.0 1.3 Iris-versicolor
56 6.5 2.8 4.6 1.5 Iris-versicolor
57 5.7 2.8 4.5 1.3 Iris-versicolor
58 6.3 3.3 4.7 1.6 Iris-versicolor
59 4.9 2.4 3.3 1.0 Iris-versicolor
60 6.6 2.9 4.6 1.3 Iris-versicolor
61 5.2 2.7 3.9 1.4 Iris-versicolor
62 5.0 2.0 3.5 1.0 Iris-versicolor
63 5.9 3.0 4.2 1.5 Iris-versicolor
64 6.0 2.2 4.0 1.0 Iris-versicolor
65 6.1 2.9 4.7 1.4 Iris-versicolor
66 5.6 2.9 3.6 1.3 Iris-versicolor
67 6.7 3.1 4.4 1.4 Iris-versicolor
68 5.6 3.0 4.5 1.5 Iris-versicolor
69 5.8 2.7 4.1 1.0 Iris-versicolor
70 6.2 2.2 4.5 1.5 Iris-versicolor
71 5.6 2.5 3.9 1.1 Iris-versicolor
72 5.9 3.2 4.8 1.8 Iris-versicolor
73 6.1 2.8 4.0 1.3 Iris-versicolor
74 6.3 2.5 4.9 1.5 Iris-versicolor
75 6.1 2.8 4.7 1.2 Iris-versicolor
76 6.4 2.9 4.3 1.3 Iris-versicolor
77 6.6 3.0 4.4 1.4 Iris-versicolor
78 6.8 2.8 4.8 1.4 Iris-versicolor
79 6.7 3.0 5.0 1.7 Iris-versicolor
80 6.0 2.9 4.5 1.5 Iris-versicolor
81 5.7 2.6 3.5 1.0 Iris-versicolor
82 5.5 2.4 3.8 1.1 Iris-versicolor
83 5.5 2.4 3.7 1.0 Iris-versicolor
84 5.8 2.7 3.9 1.2 Iris-versicolor
85 6.0 2.7 5.1 1.6 Iris-versicolor
86 5.4 3.0 4.5 1.5 Iris-versicolor
87 6.0 3.4 4.5 1.6 Iris-versicolor
88 6.7 3.1 4.7 1.5 Iris-versicolor
89 6.3 2.3 4.4 1.3 Iris-versicolor
90 5.6 3.0 4.1 1.3 Iris-versicolor
91 5.5 2.5 4.0 1.3 Iris-versicolor
92 5.5 2.6 4.4 1.2 Iris-versicolor
93 6.1 3.0 4.6 1.4 Iris-versicolor
94 5.8 2.6 4.0 1.2 Iris-versicolor
95 5.0 2.3 3.3 1.0 Iris-versicolor
96 5.6 2.7 4.2 1.3 Iris-versicolor
97 5.7 3.0 4.2 1.2 Iris-versicolor
98 5.7 2.9 4.2 1.3 Iris-versicolor
99 6.2 2.9 4.3 1.3 Iris-versicolor
100 5.1 2.5 3.0 1.1 Iris-versicolor
101 5.7 2.8 4.1 1.3 Iris-versicolor
102 6.3 3.3 6.0 2.5 Iris-virginica
103 5.8 2.7 5.1 1.9 Iris-virginica
104 7.1 3.0 5.9 2.1 Iris-virginica
105 6.3 2.9 5.6 1.8 Iris-virginica
106 6.5 3.0 5.8 2.2 Iris-virginica
107 7.6 3.0 6.6 2.1 Iris-virginica
108 4.9 2.5 4.5 1.7 Iris-virginica
109 7.3 2.9 6.3 1.8 Iris-virginica
110 6.7 2.5 5.8 1.8 Iris-virginica
111 7.2 3.6 6.1 2.5 Iris-virginica
112 6.5 3.2 5.1 2.0 Iris-virginica
113 6.4 2.7 5.3 1.9 Iris-virginica
114 6.8 3.0 5.5 2.1 Iris-virginica
115 5.7 2.5 5.0 2.0 Iris-virginica
116 5.8 2.8 5.1 2.4 Iris-virginica
117 6.4 3.2 5.3 2.3 Iris-virginica
118 6.5 3.0 5.5 1.8 Iris-virginica
119 7.7 3.8 6.7 2.2 Iris-virginica
120 7.7 2.6 6.9 2.3 Iris-virginica
121 6.0 2.2 5.0 1.5 Iris-virginica
122 6.9 3.2 5.7 2.3 Iris-virginica
123 5.6 2.8 4.9 2.0 Iris-virginica
124 7.7 2.8 6.7 2.0 Iris-virginica
125 6.3 2.7 4.9 1.8 Iris-virginica
126 6.7 3.3 5.7 2.1 Iris-virginica
127 7.2 3.2 6.0 1.8 Iris-virginica
128 6.2 2.8 4.8 1.8 Iris-virginica
129 6.1 3.0 4.9 1.8 Iris-virginica
130 6.4 2.8 5.6 2.1 Iris-virginica
131 7.2 3.0 5.8 1.6 Iris-virginica
132 7.4 2.8 6.1 1.9 Iris-virginica
133 7.9 3.8 6.4 2.0 Iris-virginica
134 6.4 2.8 5.6 2.2 Iris-virginica
135 6.3 2.8 5.1 1.5 Iris-virginica
136 6.1 2.6 5.6 1.4 Iris-virginica
137 7.7 3.0 6.1 2.3 Iris-virginica
138 6.3 3.4 5.6 2.4 Iris-virginica
139 6.4 3.1 5.5 1.8 Iris-virginica
140 6.0 3.0 4.8 1.8 Iris-virginica
141 6.9 3.1 5.4 2.1 Iris-virginica
142 6.7 3.1 5.6 2.4 Iris-virginica
143 6.9 3.1 5.1 2.3 Iris-virginica
144 5.8 2.7 5.1 1.9 Iris-virginica
145 6.8 3.2 5.9 2.3 Iris-virginica
146 6.7 3.3 5.7 2.5 Iris-virginica
147 6.7 3.0 5.2 2.3 Iris-virginica
148 6.3 2.5 5.0 1.9 Iris-virginica
149 6.5 3.0 5.2 2.0 Iris-virginica
150 6.2 3.4 5.4 2.3 Iris-virginica
151 5.9 3.0 5.1 1.8 Iris-virginica

6
test/fixtures/simple-boxplot.txt vendored Normal file
View File

@@ -0,0 +1,6 @@
┌ ┐
╷ ┌──────────┬──────────┐ ╷
1 ├───────┤ │ ├────────┤
╵ └──────────┴──────────┘ ╵
└ ┘
-50 0 50

9
test/fixtures/simple-histogram.txt vendored Normal file
View File

@@ -0,0 +1,9 @@
┌ ┐
[-60.0, -40.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1
[-40.0, -20.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2
[-20.0, 0.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2
[ 0.0, 20.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1
[ 20.0, 40.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2
[ 40.0, 60.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2
└ ┘
Frequency

View File

@@ -0,0 +1,20 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡆⠀⠀⠀⠀⠀⠀⠀⡸⢸⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢸⠀⠀⠀⠀⠀⠀⠀⡇⠸⡀⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢣⠀⠀⠀⠀⠀⠀⠀⡇⠘⡄⠀⠀⠀⠀⠀⢰⠁⠀⡇⠀⠀⠀⠀⠀⡸⠀│
│⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⡎⠘⡄⠀⠀⠀⠀⠀⢰⠁⠀⢇⠀⠀⠀⠀⠀⡸⠀⠀⢣⠀⠀⠀⠀⠀⡇⠀│
│⠀⠀⢀⠜⠘⡄⠀⠀⠀⠀⠀⢸⠀⠀⢱⠀⠀⠀⠀⠀⡜⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⢀⠇⠀│
│⠤⢤⠮⠤⠤⠼⡤⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢴⠥⠤⠤⠬⡦⠤⠤⠤⢼⠤⠤│
│⡰⠁⠀⠀⠀⠀⠱⡀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡸⠀⠀⠀⠀⢣⠀⠀⠀⡸⠀⠀⠀⠀⢇⠀⠀⠀⡸⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⢣⠀⢰⠁⠀⠀⠀⠀⠈⡆⠀⢀⠇⠀⠀⠀⠀⠸⡀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⢣⠇⠀⠀⠀⠀⠀⠀⢱⠀⢸⠀⠀⠀⠀⠀⠀⡇⠀⢰⠁⠀⠀⠀⠀⠘⡄⠀⢠⠃⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆⡇⠀⠀⠀⠀⠀⠀⢱⠀⡸⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⠀⠀⠀⠀⠀⠀⠘⡄⡇⠀⠀⠀⠀⠀⠀⢱⠀⡜⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢷⠁⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠀⠀⠀⠀⠀⠀⠀⣧⠃⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⠀⠀⠀⠀│
└────────────────────────────────────────┘
1 10

View File

@@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢇⠀⠀⠀⠀⠀⠀⠀⡎⢸⠀⠀⠀⠀⠀⠀⢠⠃│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡜⢸⠀⠀⠀⠀⠀⠀⢠⠃⠈⡆⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠸⡀⠀⠀⠀⠀⠀⢠⠃⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⢇⠀⠀⠀⠀⠀⡎⠀│
│⠀⠀⠀⡠⠳⡀⠀⠀⠀⠀⠀⢠⠃⠀⢣⠀⠀⠀⠀⠀⡜⠀⠀⢱⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀│
│⠤⢤⠼⠤⠤⠵⡤⠤⠤⠤⢤⠧⠤⠤⠼⡤⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢴⠥⠤⠤⠬⡦⠤⠤⠤⢼⠤⠤│
│⡠⠃⠀⠀⠀⠀⠱⡀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡸⠀⠀⠀⠀⢣⠀⠀⠀⡸⠀⠀⠀⠀⡇⠀⠀⠀⡜⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⠱⡀⡰⠁⠀⠀⠀⠀⠀⡇⠀⢀⠇⠀⠀⠀⠀⠸⡀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠱⠃⠀⠀⠀⠀⠀⠀⠸⡀⡸⠀⠀⠀⠀⠀⠀⢇⠀⢸⠀⠀⠀⠀⠀⠘⡄⠀⢰⠁⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡎⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⣇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠀⠀⠀⠀⠀⠀⠀⠘⣄⠇⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀│
└────────────────────────────────────────┘
1 10

View File

@@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢇⠀⠀⠀⠀⠀⠀⠀⡎⢸⠀⠀⠀⠀⠀⠀⢠⠃│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡜⢸⠀⠀⠀⠀⠀⠀⢠⠃⠈⡆⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠸⡀⠀⠀⠀⠀⠀⢠⠃⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⢇⠀⠀⠀⠀⠀⡎⠀│
│⠀⠀⠀⡠⠳⡀⠀⠀⠀⠀⠀⢠⠃⠀⢣⠀⠀⠀⠀⠀⡜⠀⠀⢱⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀│
│⠤⢤⠼⠤⠤⠵⡤⠤⠤⠤⢤⠧⠤⠤⠼⡤⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢴⠥⠤⠤⠬⡦⠤⠤⠤⢼⠤⠤│
│⡠⠃⠀⠀⠀⠀⠱⡀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡸⠀⠀⠀⠀⢣⠀⠀⠀⡸⠀⠀⠀⠀⡇⠀⠀⠀⡜⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⠱⡀⡰⠁⠀⠀⠀⠀⠀⡇⠀⢀⠇⠀⠀⠀⠀⠸⡀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠱⠃⠀⠀⠀⠀⠀⠀⠸⡀⡸⠀⠀⠀⠀⠀⠀⢇⠀⢸⠀⠀⠀⠀⠀⠘⡄⠀⢰⠁⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡎⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⣇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠀⠀⠀⠀⠀⠀⠀⠘⣄⠇⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀│
└────────────────────────────────────────┘
1 10

View File

@@ -0,0 +1,18 @@
┌─────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⣧⠀⠀⢸⢣⠀⠀⢸│
│⠀⠀⠀⠀⠀⢠⠀⠀⠀⣿⠀⠀⢸⢸⠀⠀⡇│
│⠀⠀⠀⠀⠀⣾⠀⠀⢰⢹⠀⠀⢸⢸⠀⠀⡇│
│⠀⡸⡄⠀⢀⠇⡇⠀⢸⠈⡆⠀⡎⢸⠀⠀⡇│
│⢤⠧⢧⠤⢼⠤⡧⠤⡼⠤⡧⠤⡧⠬⡦⠤⡧│
│⡎⠀⠸⡀⡎⠀⢸⠀⡇⠀⡇⠀⡇⠀⡇⢸⠀│
│⠁⠀⠀⡇⡇⠀⢸⠀⡇⠀⢸⢠⠃⠀⡇⢸⠀│
│⠀⠀⠀⠸⠀⠀⠀⣿⠀⠀⢸⢸⠀⠀⢇⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠸⣸⠀⠀⢸⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⡟⠀⠀⢸⡇⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠇⠀⠀⢸⡇⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡇⠀│
└─────────────────┘
1 10

View File

@@ -0,0 +1,19 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢇⠀⠀⠀⠀⠀⠀⠀⡎⢸⠀⠀⠀⠀⠀⠀⢠⠃│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡜⢸⠀⠀⠀⠀⠀⠀⢠⠃⠈⡆⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠸⡀⠀⠀⠀⠀⠀⢠⠃⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⢇⠀⠀⠀⠀⠀⡎⠀│
│⠀⠀⠀⡠⠳⡀⠀⠀⠀⠀⠀⢠⠃⠀⢣⠀⠀⠀⠀⠀⡜⠀⠀⢱⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀│
│⠤⢤⠼⠤⠤⠵⡤⠤⠤⠤⢤⠧⠤⠤⠼⡤⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢴⠥⠤⠤⠬⡦⠤⠤⠤⢼⠤⠤│
│⡠⠃⠀⠀⠀⠀⠱⡀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡸⠀⠀⠀⠀⢣⠀⠀⠀⡸⠀⠀⠀⠀⡇⠀⠀⠀⡜⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⠱⡀⡰⠁⠀⠀⠀⠀⠀⡇⠀⢀⠇⠀⠀⠀⠀⠸⡀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠱⠃⠀⠀⠀⠀⠀⠀⠸⡀⡸⠀⠀⠀⠀⠀⠀⢇⠀⢸⠀⠀⠀⠀⠀⠘⡄⠀⢰⠁⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡎⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⣇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠀⠀⠀⠀⠀⠀⠀⠘⣄⠇⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀│
└────────────────────────────────────────┘
1 10
X-LABEL

View File

@@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢇⠀⠀⠀⠀⠀⠀⠀⡎⢸⠀⠀⠀⠀⠀⠀⢠⠃│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡜⢸⠀⠀⠀⠀⠀⠀⢠⠃⠈⡆⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠸⡀⠀⠀⠀⠀⠀⢠⠃⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⢇⠀⠀⠀⠀⠀⡎⠀│
│⠀⠀⠀⡠⠳⡀⠀⠀⠀⠀⠀⢠⠃⠀⢣⠀⠀⠀⠀⠀⡜⠀⠀⢱⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀│
Y-LABEL │⠤⢤⠼⠤⠤⠵⡤⠤⠤⠤⢤⠧⠤⠤⠼⡤⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢴⠥⠤⠤⠬⡦⠤⠤⠤⢼⠤⠤│
│⡠⠃⠀⠀⠀⠀⠱⡀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡸⠀⠀⠀⠀⢣⠀⠀⠀⡸⠀⠀⠀⠀⡇⠀⠀⠀⡜⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⠱⡀⡰⠁⠀⠀⠀⠀⠀⡇⠀⢀⠇⠀⠀⠀⠀⠸⡀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠱⠃⠀⠀⠀⠀⠀⠀⠸⡀⡸⠀⠀⠀⠀⠀⠀⢇⠀⢸⠀⠀⠀⠀⠀⠘⡄⠀⢰⠁⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡎⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⣇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠀⠀⠀⠀⠀⠀⠀⠘⣄⠇⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀│
└────────────────────────────────────────┘
1 10

18
test/fixtures/simple-lineplot.txt vendored Normal file
View File

@@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢇⠀⠀⠀⠀⠀⠀⠀⡎⢸⠀⠀⠀⠀⠀⠀⢠⠃│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⡜⢸⠀⠀⠀⠀⠀⠀⢠⠃⠈⡆⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠸⡀⠀⠀⠀⠀⠀⢠⠃⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⢇⠀⠀⠀⠀⠀⡎⠀│
│⠀⠀⠀⡠⠳⡀⠀⠀⠀⠀⠀⢠⠃⠀⢣⠀⠀⠀⠀⠀⡜⠀⠀⢱⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀│
│⠤⢤⠼⠤⠤⠵⡤⠤⠤⠤⢤⠧⠤⠤⠼⡤⠤⠤⠤⢤⠧⠤⠤⠬⡦⠤⠤⠤⢴⠥⠤⠤⠬⡦⠤⠤⠤⢼⠤⠤│
│⡠⠃⠀⠀⠀⠀⠱⡀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡸⠀⠀⠀⠀⢣⠀⠀⠀⡸⠀⠀⠀⠀⡇⠀⠀⠀⡜⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⠱⡀⡰⠁⠀⠀⠀⠀⠀⡇⠀⢀⠇⠀⠀⠀⠀⠸⡀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠱⠃⠀⠀⠀⠀⠀⠀⠸⡀⡸⠀⠀⠀⠀⠀⠀⢇⠀⢸⠀⠀⠀⠀⠀⠘⡄⠀⢰⠁⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡎⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⣇⠇⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠀⠀⠀⠀⠀⠀⠀⠘⣄⠇⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀│
└────────────────────────────────────────┘
1 10

10
test/fixtures/simple.tsv vendored Normal file
View File

@@ -0,0 +1,10 @@
-10
10
-20
20
-30
30
-40
40
-50
50
1 -10
2 10
3 -20
4 20
5 -30
6 30
7 -40
8 40
9 -50
10 50

1
test/fixtures/simpleT.tsv vendored Normal file
View File

@@ -0,0 +1 @@
-10 10 -20 20 -30 30 -40 40 -50 50
1 -10 10 -20 20 -30 30 -40 40 -50 50

View File

@@ -8,4 +8,10 @@ class YouPlotCommandTest < Test::Unit::TestCase
assert_equal([%i[a b c], [3, 2, 1]], @m.count_values(%i[a a a b b c]))
assert_equal([%i[c b a], [3, 2, 1]], @m.count_values(%i[a b b c c c]))
end
test :count_values_non_tally do
@m = YouPlot::Backends::Processing
assert_equal([%i[a b c], [3, 2, 1]], @m.count_values(%i[a a a b b c], tally: false))
assert_equal([%i[c b a], [3, 2, 1]], @m.count_values(%i[a b b c c c], tally: false))
end
end

View File

@@ -125,7 +125,7 @@ class YouPlotDSVTest < Test::Unit::TestCase
[n, n, 6]], @m.get_series([[1],
[2, 4],
[3, 5, 6]], false, false))
assert_equal([[], [] ,[]], @m.get_series([[1, 2, 3]], true, false))
assert_equal([[], [], []], @m.get_series([[1, 2, 3]], true, false))
end
end

View File

@@ -3,7 +3,7 @@
require 'tempfile'
require_relative '../test_helper'
class YouPlotCommandTest < Test::Unit::TestCase
class YouPlotIRISTest < Test::Unit::TestCase
class << self
def startup
@stdin = $stdin.dup
@@ -104,15 +104,26 @@ class YouPlotCommandTest < Test::Unit::TestCase
assert_equal fixture('iris-boxplot.txt'), @stderr_file.read
end
# test :c do
# YouPlot::Command.new(['count', '-H', '-d,']).run
# assert_equal fixture('iris-count.txt'), @stderr_file.read
# end
# test :count do
# YouPlot::Command.new(['c', '-H', '-d,']).run
# assert_equal fixture('iris-count.txt'), @stderr_file.read
# end
test :plot_output_stdout do
YouPlot::Command.new(['bar', '-o', '-H', '-d,', '-t', 'IRIS-BARPLOT']).run
assert_equal '', @stderr_file.read
assert_equal fixture('iris-barplot.txt'), @stdout_file.read
end
test :data_output_stdout do
YouPlot::Command.new(['bar', '-O', '-H', '-d,', '-t', 'IRIS-BARPLOT']).run
assert_equal fixture('iris-barplot.txt'), @stderr_file.read
assert_equal File.read(File.expand_path('../fixtures/iris.csv', __dir__)), @stdout_file.read
assert_equal fixture('iris.csv'), @stdout_file.read
end
%i[colors color colours colour].each do |cmd_name|
@@ -128,4 +139,18 @@ class YouPlotCommandTest < Test::Unit::TestCase
assert_equal '', @stderr_file.read
assert_equal fixture('colors.txt'), @stdout_file.read
end
test :unrecognized_command do
assert_raise(YouPlot::Command::Parser::Error) do
YouPlot::Command.new(['abracadabra', '--hadley', '--wickham']).run
end
assert_equal '', @stderr_file.read
assert_equal '', @stdout_file.read
end
test :encoding do
$stdin = File.open(File.expand_path('../fixtures/iris_utf16.csv', __dir__), 'r')
YouPlot::Command.new(['s', '--encoding', 'UTF-16', '-H', '-d,', '-t', 'IRIS-SCATTER']).run
assert_equal fixture('iris-scatter.txt'), @stderr_file.read
end
end

205
test/youplot/simple_test.rb Normal file
View File

@@ -0,0 +1,205 @@
# frozen_string_literal: true
require 'tempfile'
require_relative '../test_helper'
class YouPlotSimpleTest < Test::Unit::TestCase
class << self
def startup
@stdin = $stdin.dup
@stdout = $stdout.dup
@stderr = $stderr.dup
end
def shutdown
$stdin = @stdin
$stdout = @stdout
$stderr = @stderr
end
end
def setup
$stdin = File.open(File.expand_path('../fixtures/simple.tsv', __dir__), 'r')
@stderr_file = Tempfile.new
@stdout_file = Tempfile.new
$stderr = @stderr_file
$stdout = @stdout_file
end
def teardown
@stderr_file.close
end
def fixture(fname)
File.read(File.expand_path("../fixtures/#{fname}", __dir__))
end
test :bar do
assert_raise(ArgumentError) do
YouPlot::Command.new(['bar']).run
end
end
test :barplot do
assert_raise(ArgumentError) do
YouPlot::Command.new(['barplot']).run
end
end
test :hist do
YouPlot::Command.new(['hist']).run
assert_equal fixture('simple-histogram.txt'), @stderr_file.read
end
test :histogram do
YouPlot::Command.new(['histogram']).run
assert_equal fixture('simple-histogram.txt'), @stderr_file.read
end
test :line do
YouPlot::Command.new(['line']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :lineplot do
YouPlot::Command.new(['lineplot']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :lines do
assert_raise(YouPlot::Backends::UnicodePlotBackend::Error) do
YouPlot::Command.new(['lines']).run
end
end
test :lineplots do
assert_raise(YouPlot::Backends::UnicodePlotBackend::Error) do
YouPlot::Command.new(['lineplots']).run
end
end
test :s do
assert_raise(YouPlot::Backends::UnicodePlotBackend::Error) do
YouPlot::Command.new(['s']).run
end
end
test :scatter do
assert_raise(YouPlot::Backends::UnicodePlotBackend::Error) do
YouPlot::Command.new(['scatter']).run
end
end
test :d do
assert_raise(YouPlot::Backends::UnicodePlotBackend::Error) do
YouPlot::Command.new(['d']).run
end
end
test :density do
assert_raise(YouPlot::Backends::UnicodePlotBackend::Error) do
YouPlot::Command.new(['density']).run
end
end
test :box do
YouPlot::Command.new(['box']).run
assert_equal fixture('simple-boxplot.txt'), @stderr_file.read
end
test :boxplot do
YouPlot::Command.new(['boxplot']).run
assert_equal fixture('simple-boxplot.txt'), @stderr_file.read
end
# test :c do
# omit
# YouPlot::Command.new(['count', '-H', '-d,']).run
# assert_equal fixture('iris-count.txt'), @stderr_file.read
# end
# test :count do
# omit
# YouPlot::Command.new(['c', '-H', '-d,']).run
# assert_equal fixture('iris-count.txt'), @stderr_file.read
# end
test :plot_output_stdout do
YouPlot::Command.new(['line', '-o']).run
assert_equal '', @stderr_file.read
assert_equal fixture('simple-lineplot.txt'), @stdout_file.read
end
test :data_output_stdout do
YouPlot::Command.new(['box', '-O']).run
assert_equal fixture('simple-boxplot.txt'), @stderr_file.read
assert_equal fixture('simple.tsv'), @stdout_file.read
end
test :line_transpose do
$stdin = File.open(File.expand_path('../fixtures/simpleT.tsv', __dir__), 'r')
YouPlot::Command.new(['line', '--transpose']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :line_T do
$stdin = File.open(File.expand_path('../fixtures/simpleT.tsv', __dir__), 'r')
YouPlot::Command.new(['line', '-T']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :line_xlabel do
YouPlot::Command.new(['line', '--xlabel', 'X-LABEL']).run
assert_equal fixture('simple-lineplot-xlabel.txt'), @stderr_file.read
end
test :line_x do
YouPlot::Command.new(['line', '-x', 'X-LABEL']).run
assert_equal fixture('simple-lineplot-xlabel.txt'), @stderr_file.read
end
test :line_ylabel do
YouPlot::Command.new(['line', '--ylabel', 'Y-LABEL']).run
assert_equal fixture('simple-lineplot-ylabel.txt'), @stderr_file.read
end
test :line_y do
YouPlot::Command.new(['line', '-y', 'Y-LABEL']).run
assert_equal fixture('simple-lineplot-ylabel.txt'), @stderr_file.read
end
test :line_width do
YouPlot::Command.new(['line', '--width', '17']).run
assert_equal fixture('simple-lineplot-width-17.txt'), @stderr_file.read
end
test :line_w do
YouPlot::Command.new(['line', '--w', '17']).run
assert_equal fixture('simple-lineplot-width-17.txt'), @stderr_file.read
end
test :line_height do
YouPlot::Command.new(['line', '--height', '17']).run
assert_equal fixture('simple-lineplot-height-17.txt'), @stderr_file.read
end
test :line_h do
YouPlot::Command.new(['line', '--height', '17']).run
assert_equal fixture('simple-lineplot-height-17.txt'), @stderr_file.read
end
test :line_margin do
YouPlot::Command.new(['line', '--margin', '17']).run
assert_equal fixture('simple-lineplot-margin-17.txt'), @stderr_file.read
end
test :line_m do
YouPlot::Command.new(['line', '--m', '17']).run
assert_equal fixture('simple-lineplot-margin-17.txt'), @stderr_file.read
end
test :line_padding do
YouPlot::Command.new(['line', '--padding', '17']).run
assert_equal fixture('simple-lineplot-padding-17.txt'), @stderr_file.read
end
end

View File

@@ -3,7 +3,19 @@
require_relative 'test_helper'
class YouPlotTest < Test::Unit::TestCase
def test_that_it_has_a_version_number
def teardown
YouPlot.run_as_executable = false
end
test :it_has_a_version_number do
assert_kind_of String, ::YouPlot::VERSION
end
test :run_as_executable do
assert_equal false, YouPlot.run_as_executable
assert_equal false, YouPlot.run_as_executable?
YouPlot.run_as_executable = true
assert_equal true, YouPlot.run_as_executable
assert_equal true, YouPlot.run_as_executable?
end
end

View File

@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
spec.files = Dir['*.{md,txt}', '{lib,exe}/**/*']
spec.bindir = 'exe'
spec.executables = ['uplot', 'youplot']
spec.executables = %w[uplot youplot]
spec.require_paths = ['lib']
spec.add_runtime_dependency 'unicode_plot'