Compare commits

...

199 Commits
v0.3.1 ... main

Author SHA1 Message Date
kojix2
cd638f7ec1
Enable workflow_dispatch for test 2024-12-26 09:02:26 +09:00
kojix2
9aabd4a877 v0.4.6 2024-07-20 15:42:36 +09:00
kojix2
48f4af10c3 Add csv to gemspec
csv  is not part of the default gems since Ruby 3.4.0
2024-07-20 15:36:48 +09:00
kojix2
b0b03053af Add Ruby 3.4 to CI 2024-07-20 15:30:16 +09:00
kojix2
2a8c621be6 Update GitHub Actions versions in ci.yml and doc.yml 2024-07-20 15:29:02 +09:00
kojix2
4c45143edb
Update README.md
Adjust the order of installation commands
2024-06-25 14:01:30 +09:00
Naser Aleisa
ef6794e32f docs: add nix command to installation 2024-06-25 13:58:23 +09:00
kojix2
7cad6753ca Remove Ruby 2.5 from GitHub Actions testing
CRuby < 2.6 does not support macos-arm64
2024-06-09 23:51:22 +09:00
Gabor Szarnyas
9b239cef89 Fix typo: baplot -> barplot 2024-06-09 23:45:48 +09:00
kojix2
6451ab40d4
Update FUNDING.yml 2024-02-10 09:27:42 +09:00
kojix2
575a780321
Added Ruby 3.3 to CI and removed 2.4 2023-12-26 14:42:00 +09:00
muxator
666df42e07
readme: fix typo for "-o" option (#47)
If you want to output to "standard input" -> "standard output"
2023-11-15 19:39:42 +09:00
kojix2
a2d04dafa3
Update README.md
How to install with Anaconda
2023-04-28 06:11:36 +09:00
kojix2
7d595d7ede
Update README.md 2023-04-10 11:08:01 +09:00
kojix2
99bdbb06d1
Add examples that work offline to the README (#42)
Fix #41
Reported by @zhangwenda0518 Thanks!
2023-04-09 16:07:48 +09:00
gemmaro
60f9cb32dd
Added Guix installation (#40)
Guix issue tracker: https://issues.guix.gnu.org/62161
2023-04-06 17:23:15 +09:00
TO226
1a3a80568d Fix a missing link 2023-02-26 11:28:47 +09:00
kojix2
3ee329908b
Update README.md
YouPlot is available via homebrew
Reported by @zachvalenta (#33) Thanks!
2023-02-13 14:35:49 +09:00
kojix2
5695bbe91f v0.4.5 2023-01-09 20:37:34 +09:00
kojix2
0e2f8014fd Improved error messages 2023-01-05 13:54:47 +09:00
kojix2
a6c054f596 Added comment 2023-01-05 13:45:39 +09:00
kojix2
26050a2f87 Added config option to allow configuration files to be specified later 2023-01-05 13:40:52 +09:00
kojix2
8eca14a70d Fix typo 2023-01-05 12:56:06 +09:00
kojix2
654dbfca62 Added configuration file paths and improved messages 2023-01-05 12:54:43 +09:00
kojix2
433c24e710
Added configuration section to README 2023-01-05 12:30:02 +09:00
kojix2
b1baa4073c Added --config option 2023-01-05 12:20:56 +09:00
kojix2
27a84a4df1 Minor refactoring 2023-01-05 12:05:11 +09:00
kojix2
f8bd152a63 Improved the way help is displayed
- Add `help` to the subcommand.
- Use same method to display help in stdout or stderr.
2023-01-05 11:57:46 +09:00
kojix2
f9ffca636f Rubocop auto correct 2023-01-05 11:48:19 +09:00
kojix2
83b1da9b96 Refactoring of config file reading 2023-01-05 11:40:51 +09:00
kojix2
1f41e79952 Add alias l for line and alias ls for lins as a trial (#17) 2023-01-05 10:53:23 +09:00
kojix2
85ed440c52
Add Ruby 3.2 to CI 2022-12-25 21:00:53 +09:00
kojix2
16525233f3
Update doc.yml
Use latest ruby
2022-12-16 21:04:44 +09:00
kojix2
4efdc79e30 Use actions/checkout v3 2022-10-19 09:22:26 +09:00
kojix2
19f05e57ac v0.4.4 2022-08-02 17:05:30 +09:00
kojix2
f11fd6babb Consistent variable names 2022-08-02 16:58:48 +09:00
kojix2
9d69c4322c
Make configuration files available (#30) 2022-07-31 22:37:50 +09:00
kojix2
41c0d37a13 Friendly error messages 2022-05-25 16:24:13 +09:00
kojix2
a1dcc532ea Friendly error messages 2022-05-25 16:03:33 +09:00
kojix2
523700348c
Create doc.yml 2022-03-24 18:47:41 +09:00
kojix2
e34ab2b097
Update README.md
Do you need commit rights to my repository?
Do you want to get admin rights and take over the project?
If so, please feel free to contact kojix2.
2022-02-13 13:05:13 +09:00
kojix2
f8fe010d27
Add Ruby3.1 to CI (#29) 2021-12-30 11:54:15 +09:00
kojix2
e76d4f279e v0.4.3 2021-11-19 14:09:46 +09:00
kojix2
3a1a29424d Remove add_development_dependency from gem 2021-11-19 14:03:57 +09:00
kojix2
b78da2388a Rubocop auto correct 2021-11-19 13:56:09 +09:00
KIKISeries
a7bb75e87d Fix a typo
S -> s
2021-07-14 09:56:47 +09:00
kojix2
ca9f97a7dc Specify the version of UnicodePlot 2021-07-12 14:56:41 +09:00
kojix2
f67a5ce913 Add comments on the run_as_executable variable 2021-07-12 14:49:34 +09:00
kojix2
dbbfd366be Remove unused variable 2021-07-11 08:59:44 +09:00
kojix2
42cadee553 Improved CI
Remove needless line
2021-07-11 08:43:47 +09:00
kojix2
e689c69838
Update CI
* Enable bundler-cache
2021-07-11 08:38:05 +09:00
kojix2
c53169e9ee
Update README.md (#24) 2021-07-03 07:22:19 +09:00
kojix2
95a35399a2 Show a error message when linecolor is specified as a number 2021-07-03 06:52:37 +09:00
kojix2
7c00f95962
Fix Readme style 2021-06-20 19:10:09 +09:00
kojix2
fcbf9305d7 Add StringIO for consistency 2021-06-18 10:43:28 +09:00
kojix2
04eddfd79b Fix typo 2021-06-17 08:19:04 +09:00
kojix2
125c2291d5 Add categorical/date to README 2021-06-17 08:13:58 +09:00
kojix2
6a72418d01 Update README 2021-06-17 07:49:51 +09:00
kojix2
72a56659de Removed -x and -y options
The -x and -y options now stand for --xlabel and --ylabel.

These options should be used to specify the series in the future.
2021-06-17 07:47:14 +09:00
kojix2
858792fa99
Fix a typo 2021-06-14 13:08:45 +09:00
kojix2
e7079c56a2
Update README.md 2021-06-14 13:07:29 +09:00
kojix2
bb8a16a327 Swap the order of count and color in help 2021-06-14 11:37:06 +09:00
kojix2
be0f706231
Update README.md 2021-06-14 11:23:52 +09:00
kojix2
e5c87fbe6f
Add recommended tools to README.md 2021-06-11 10:48:33 +09:00
kojix2
4f17579846 v0.4.2 2021-06-10 11:35:35 +09:00
kojix2
81df12a033 Changed width option from Integer to Numeric
This is to keep consistency with other options
2021-06-10 11:33:46 +09:00
kojix2
a8073bc684 Convert xlim and ylim types to numbers
Fix (#18)
2021-06-10 11:19:35 +09:00
kojix2
23bb767afe Revert "Accept hyphens as an output option"
This reverts commit dfc027d972.

No need to change.
2021-06-08 17:44:53 +09:00
kojix2
dfc027d972 Accept hyphens as an output option 2021-06-07 23:51:46 +09:00
kojix2
7a1bacccbc
Update README.md
Center the logo and badge
2021-06-04 00:20:54 +09:00
kojix2
92989eb582 🚀 Transferred YouPlot to RedDataTools 2021-06-03 12:01:07 +09:00
kojix2
33c68c0607 v0.4.1 2021-06-03 11:06:59 +09:00
kojix2
30b3b6e7d3 Rubocop auto correct 2021-06-03 11:03:49 +09:00
kojix2
d49a11bb7a Merge branch 'v0.4.1' 2021-06-03 11:01:20 +09:00
kojix2
c573d690bc Revert "Set the Gem Ruby version to 2.6 or higher"
I changed my mind, it better work on 2.4!

This reverts commit 2649959745.
2021-06-03 10:53:12 +09:00
kojix2
f823377c50 Make tests pass in Ruby 2.4 2021-06-03 10:48:47 +09:00
kojix2
d9777435a4 Add Test on ruby 2.4 2021-06-03 10:39:43 +09:00
kojix2
2649959745 Set the Gem Ruby version to 2.6 or higher 2021-06-03 10:32:20 +09:00
kojix2
4651c697d4 Add reverse to count 2021-05-31 22:50:11 +09:00
kojix2
49626d54e1 v0.4.0 2021-05-30 23:00:19 +09:00
kojix2
f824135653 Clarify the Output type a little 2021-05-29 16:17:59 +09:00
kojix2
2eca86268c Add comments to command class 2021-05-29 14:59:42 +09:00
kojix2
85d818d8ca Refactoring and commenting DSV module 2021-05-29 13:34:19 +09:00
kojix2
b484a3a96f Refactor parser 2021-05-29 11:19:48 +09:00
kojix2
7e97d44caf Add comments 2021-05-29 10:28:56 +09:00
kojix2
d30942fef6 Rename default_parser -> base_parser 2021-05-29 10:28:48 +09:00
kojix2
72f59887de Fix order of tests 2021-05-29 09:45:58 +09:00
kojix2
2005eaf871
Fix typo in README 2021-05-29 08:18:17 +09:00
kojix2
6edd66662d Fix monochrome and color-output options 2021-05-28 17:15:30 +09:00
kojix2
977d3beb2d count: if the values are the same, sort by name 2021-05-28 14:04:18 +09:00
kojix2
f57090cc9b Add simple tests for count again 2021-05-28 12:36:06 +09:00
kojix2
cfbbc33286 Adjust summary_width
Try to keep it within 80 characters
2021-05-28 12:31:06 +09:00
kojix2
74f7a2435d Added an error message suggesting to specify the character encoding option 2021-05-28 11:47:54 +09:00
kojix2
801c2a4920 Fix test class name 2021-05-28 11:21:00 +09:00
kojix2
8f52955c19 Moved comments to make method chaining work in Ruby 2.6 and below 2021-05-28 10:43:05 +09:00
kojix2
a4e747969f Use value_counts if tally is not available 2021-05-28 10:24:45 +09:00
kojix2
9e15c0ac2a Rename UnicodePlotBackend -> Backend::UnicodePlot 2021-05-28 10:06:58 +09:00
kojix2
97d6c3e73f Revert "Use value_counts instead of tally" 2021-05-28 09:36:08 +09:00
kojix2
715ec8f908 Add a test for count
Check that it works. This is not enough
2021-05-27 23:49:03 +09:00
kojix2
607e490d7a Remove Processing module 2021-05-27 23:18:08 +09:00
kojix2
86c0d8ed53 Use enumerable-statistics's value_counts instead of tally 2021-05-27 23:04:23 +09:00
kojix2
29dfe424e7 Flatten the module hierarchy
Move Parser and Options up
2021-05-27 21:50:05 +09:00
kojix2
7c42d9a444 Move Plot::Params to Parameters 2021-05-27 21:15:06 +09:00
kojix2
54b70f1f27 Update README.md 2021-05-24 14:09:53 +09:00
kojix2
69167a6f44
Fix README.md 2021-05-24 13:31:47 +09:00
kojix2
f596391ad9 v0.3.5 2021-05-21 09:35:49 +09:00
kojix2
cf29934f08
ci: Remove Ruby 2.5
EOL
2021-04-22 10:04:08 +09:00
kojix2
56d00cae31
Fix typo in README.md 2021-03-22 13:45:25 +09:00
kojix2
3093c7b715
Fix doc badge 2021-03-09 16:46:44 +09:00
kojix2
7f5f33a999
Update README.md
Make the logo smaller
2021-03-05 19:52:42 +09:00
kojix2
5ec3d6ca3f
Update Funding.yml
Removed patreon
2021-02-16 22:32:47 +09:00
kojix2
0dcfe86c37
Update FUNDING.yml 2021-02-16 22:17:18 +09:00
kojix2
5b53b03769 Add logo created by sampo grafikka
Thanks!
2021-02-10 00:43:26 +09:00
kojix2
eff998be38
Add contributing message 2021-02-09 23:01:37 +09:00
kojix2
8c3bf4c79a Fix tests 2021-02-04 18:18:55 +09:00
kojix2
41acac8811 Add color-output and monochrome options 2021-02-04 18:09:47 +09:00
kojix2
95599fbf4f Fixed default values for progressive option 2021-02-04 17:22:36 +09:00
kojix2
6ccce30377 Fix xscale option 2021-01-27 17:30:28 +09:00
kojix2
75db26da53 Rubocop auto correct 2021-01-27 17:30:14 +09:00
kojix2
b165de43ed Add grid tests for lineplot 2021-01-22 11:23:18 +09:00
kojix2
f18c72228c Add xlim ylim tests for lineplot 2021-01-22 11:11:15 +09:00
kojix2
c4a726fd08 Change where exceptions are caught 2021-01-22 11:07:33 +09:00
kojix2
96d11f8d0e Improved style: use of hear document 2021-01-22 11:04:54 +09:00
kojix2
ac0f5d4efa Add tests for canvas and symbol options 2021-01-22 09:39:07 +09:00
kojix2
f4f7267ec7 Add unicode_plot constant tests 2021-01-21 20:50:25 +09:00
kojix2
6f8f9275d2 Add tests for border options 2021-01-21 19:48:43 +09:00
kojix2
58f6580e3f Improved border desc 2021-01-21 18:23:01 +09:00
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
kojix2
7edbe6f41b Fix gemspec 2021-01-02 00:30:24 +09:00
kojix2
61168a6223 v0.3.3 2021-01-02 00:27:08 +09:00
kojix2
00b8aee572
Centered the images in the README 2021-01-01 23:06:10 +09:00
kojix2
e760ae504b
Add new logo under improvement (#13)
* Add the new logo being created

Created by sampo grafiikka
thanks!!!
2021-01-01 22:54:01 +09:00
kojix2
fae4248d1f Corrected English text
Fixed by @yutaas. Thanks!!!

Co-authored-by: Yuta Asano <YutaAsano1986@gmail.com>
2020-12-28 15:05:06 +09:00
kojix2
73b7693915 Fix CI 2020-12-26 22:27:33 +09:00
kojix2
7f3e430cc9 Add Ruby 3.0 to CI 2020-12-26 22:10:49 +09:00
kojix2
1b525f1335 Support headers in progressive mode 2020-12-21 21:43:31 +09:00
kojix2
6d707533a0 Allow DSV to accept single line header 2020-12-21 21:29:39 +09:00
kojix2
60fb611160 Improved progressive mode 2020-12-21 20:51:52 +09:00
kojix2
f0861bcac4
Add experimental progressive mode 2020-12-21 17:09:47 +09:00
kojix2
1669024325
Update README.md 2020-12-21 17:07:22 +09:00
kojix2
9a7f066f3b Rename input to parse 2020-12-21 16:09:37 +09:00
kojix2
f0c5e631f7 Rename CmdOptions to Options 2020-12-21 14:39:22 +09:00
kojix2
fd7b755c79 Rename DSVReader to DSV 2020-12-21 14:31:54 +09:00
kojix2
d6e1840e58
Update README.md 2020-12-21 08:02:12 +09:00
kojix2
59b81606f5
Fix a typo 2020-12-19 20:26:24 +09:00
kojix2
b5a88e10a2
Update README.md
* Mention that English corrections are welcome.
2020-12-19 18:46:01 +09:00
kojix2
6335386762
Update README.md
* Fix typo
* head line
* delimiter
2020-12-19 18:42:04 +09:00
kojix2
887b9d3c53
Update README.md
* Write about `--fmt` option
2020-12-19 18:33:37 +09:00
kojix2
eb317e2bb5 v0.3.2 2020-12-17 12:42:00 +09:00
kojix2
edd081562e Fix color command 2020-12-17 12:38:32 +09:00
kojix2
cc076d5cfe Fix README.md 2020-12-17 11:43:59 +09:00
kojix2
6f5b73887d
Update README.md 2020-12-16 18:48:34 +09:00
kojix2
e18344cc13
Update README.md 2020-12-16 18:47:55 +09:00
kojix2
ae1e7ba44e
Update README.md 2020-12-16 18:18:29 +09:00
kojix2
4f78920915
Update README.md 2020-12-16 17:40:50 +09:00
kojix2
115ff6623d
Update READMED.md 2020-12-16 16:51:07 +09:00
kojix2
1b666038bb Changes the default value to stdout if no argument is specified with the -o option
#9
2020-12-16 12:51:16 +09:00
kojix2
b368dc44b4
Add zenodo badge 2020-12-15 14:31:32 +09:00
kojix2
9581cf730a Fix style 2020-12-14 22:15:45 +09:00
kojix2
566cee883a Refactored comand class 2020-12-14 22:02:18 +09:00
kojix2
0aa6de0de5 Added CmdOptions struct 2020-12-14 15:54:54 +09:00
kojix2
5d1a4fdf3c Rename params -> plot_params 2020-12-14 15:02:32 +09:00
kojix2
a5cdc94bb0 Fix order 2020-12-13 23:46:36 +09:00
kojix2
f2b7b94a09
Add logo to README (#7) 2020-12-13 15:03:01 +09:00
kojix2
1d92ab8e2d
Update screenshots in README 2020-12-13 09:52:53 +09:00
kojix2
98e294fae9 Add new IRIS.tsv for REDAME 2020-12-13 07:53:55 +09:00
kojix2
0af084916e
Improved README 2020-12-13 00:50:03 +09:00
kojix2
dee53a003c Add iris_readme.tsv 2020-12-12 22:10:34 +09:00
57 changed files with 2563 additions and 786 deletions

1
.github/FUNDING.yml vendored
View File

@ -1,2 +1 @@
ko_fi: kojix2
patreon: kojix2

View File

@ -1,18 +1,17 @@
name: test
on: [push, pull_request]
on: [push, pull_request, workflow_dispatch]
jobs:
build:
name: ${{ matrix.os }} Ruby ${{ matrix.ruby }}
runs-on: ${{ matrix.os }}-latest
strategy:
matrix:
os: ['ubuntu', 'macos']
ruby: [ '2.5', '2.6', '2.7' ]
os: ["ubuntu", "macos"]
ruby: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-ruby@v1
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- run: gem install bundler
- run: bundle install
bundler-cache: true
- run: bundle exec rake test

23
.github/workflows/doc.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: doc
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ruby
- name: Generate document
run: gem install -N yard && yard doc
- name: Publish Documentation on GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doc

View File

@ -4,3 +4,9 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in youplot.gemspec
gemspec
group :test do
gem 'rake'
gem 'simplecov'
gem 'test-unit'
end

363
README.md
View File

@ -1,147 +1,318 @@
# YouPlot
<div align="center">
<img src="logo.svg">
<hr>
<a href="https://github.com/red-data-tools/YouPlot/actions/workflows/ci.yml"><img alt="Build Status" src="https://github.com/red-data-tools/YouPlot/workflows/test/badge.svg"></a>
<a href="https://rubygems.org/gems/youplot/"><img alt="Gem Version" src="https://badge.fury.io/rb/youplot.svg"></a>
<a href="https://zenodo.org/badge/latestdoi/283230219"><img alt="DOI" src="https://zenodo.org/badge/283230219.svg"></a>
<a href="https://rubydoc.info/gems/youplot/"><img alt="Docs Stable" src="https://img.shields.io/badge/docs-stable-blue.svg"></a>
<a href="LICENSE.txt"><img alt="The MIT License" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
![Build Status](https://github.com/kojix2/youplot/workflows/test/badge.svg)
[![Gem Version](https://badge.fury.io/rb/youplot.svg)](https://badge.fury.io/rb/youplot)
[![Docs Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://rubydoc.info/gems/youplot)
[![The MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
YouPlot is a command line tool that draws plots on the terminal.
Create ASCII charts on the terminal with data from standard streams in the pipeline.
:bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
:bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
</div>
## Installation
```
brew install youplot
```
```
gem install youplot
```
## Screenshots
**histogram**
```sh
ruby -r numo/narray -e "puts Numo::DFloat.new(1000).rand_norm.to_a" \
| uplot hist --nbins 15
```
nix shell nixpkgs#youplot
```
<img src="https://i.imgur.com/wpsoGJq.png" width="75%" height="75%">
```
guix install youplot
```
```
conda install -c conda-forge ruby
conda install -c conda-forge compilers
gem install youplot
```
## Quick Start
<img alt="barplot" src="https://user-images.githubusercontent.com/5798442/101999903-d36a2d00-3d24-11eb-9361-b89116f44122.png" width=160> <img alt="histogram" src="https://user-images.githubusercontent.com/5798442/101999820-21cafc00-3d24-11eb-86db-e410d19b07df.png" width=160> <img alt="scatter" src="https://user-images.githubusercontent.com/5798442/101999827-27284680-3d24-11eb-9903-551857eaa69c.png" width=160> <img alt="density" src="https://user-images.githubusercontent.com/5798442/101999828-2abbcd80-3d24-11eb-902c-2f44266fa6ae.png" width=160> <img alt="boxplot" src="https://user-images.githubusercontent.com/5798442/101999830-2e4f5480-3d24-11eb-8891-728c18bf5b35.png" width=160>
`uplot <command> [options] <data.tsv>`
### barplot
```sh
curl -sL https://git.io/ISLANDScsv \
| sort -nk2 -t, \
| tail -n15 \
| uplot bar -d, -t "Areas of the World's Major Landmasses"
```
<p align="center">
<img alt="barplot" src="https://user-images.githubusercontent.com/5798442/101999903-d36a2d00-3d24-11eb-9361-b89116f44122.png">
</p>
```sh
# For offline user: Sorts files in a directory by size and shows a bar graph.
ls -l | awk '{print $9, $5}' | sort -nk 2 | uplot bar -d ' '
```
### histogram
```sh
echo -e "from numpy import random;" \
"n = random.randn(10000);" \
"print('\\\n'.join(str(i) for i in n))" \
| python \
| python3 \
| uplot hist --nbins 20
```
<img src="https://i.imgur.com/97R2MQx.png" width="75%" height="75%">
<p align="center">
<img alt="histogram" src="https://user-images.githubusercontent.com/5798442/101999820-21cafc00-3d24-11eb-86db-e410d19b07df.png">
</p>
**scatter**
### lineplot
```sh
curl -s https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv \
| cut -f1-4 -d, \
| uplot scatter -H -d, -t IRIS
curl -sL https://git.io/AirPassengers \
| cut -f2,3 -d, \
| uplot line -d, -w 50 -h 15 -t AirPassengers --xlim 1950,1960 --ylim 0,600
```
<img src="https://i.imgur.com/STX7bFT.png" width="75%" height="75%">
**line**
<p align="center">
<img alt="lineplot" src="https://user-images.githubusercontent.com/5798442/101999825-24c5ec80-3d24-11eb-99f4-c642e8d221bc.png">
</p>
```sh
curl -s https://www.mhlw.go.jp/content/pcr_positive_daily.csv \
| cut -f2 -d, \
| uplot line -w 50 -h 15 -t 'PCR positive tests' --xlabel Date --ylabel number
# For offline users: Calculates sin values (0-2*pi) and plots a sine wave.
python3 -c '
from math import sin, pi
data = "\n".join(f"{i*pi/50}\t{sin(i*pi/50)}" for i in range(101))
print(data)' | uplot line
```
<img src="https://i.imgur.com/PVl5dsa.png" width="75%" height="75%">
**box**
### scatter
```sh
curl -s https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv \
| cut -f1-4 -d, \
| uplot box -H -d, -t IRIS
curl -sL https://git.io/IRIStsv \
| cut -f1-4 \
| uplot scatter -H -t IRIS
```
<img src="https://i.imgur.com/sNI4SmN.png" width="75%" height="75%">
<p align="center">
<img alt="scatter" src="https://user-images.githubusercontent.com/5798442/101999827-27284680-3d24-11eb-9903-551857eaa69c.png">
</p>
**colors**
```sh
uplot colors
# For offline users
cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot scatter -H -d, -t IRIS
```
<img src="https://i.imgur.com/LxyHQsz.png">
### density
```sh
curl -sL https://git.io/IRIStsv \
| cut -f1-4 \
| uplot density -H -t IRIS
```
<p align="center">
<img alt="density" src="https://user-images.githubusercontent.com/5798442/101999828-2abbcd80-3d24-11eb-902c-2f44266fa6ae.png">
</p>
```sh
# For offline users
cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot density -H -d, -t IRIS
```
### boxplot
```sh
curl -sL https://git.io/IRIStsv \
| cut -f1-4 \
| uplot boxplot -H -t IRIS
```
<p align="center">
<img alt="boxplot" src="https://user-images.githubusercontent.com/5798442/101999830-2e4f5480-3d24-11eb-8891-728c18bf5b35.png">
</p>
```sh
# For offline users
cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot boxplot -H -d, -t IRIS
```
### count
Count processes by user ID.
```sh
ps aux | awk '{print $1}' | uplot count
```
Count the number of chromosomes where genes are located.
```sh
cat gencode.v35.annotation.gff3 \
| grep -v '#' | grep 'gene' | cut -f1 \
| uplot count -t "The number of human gene annotations per chromosome" -c blue
```
<p align="center">
<img alt="count" src="https://user-images.githubusercontent.com/5798442/101999832-30b1ae80-3d24-11eb-96fe-e5000bed1f5c.png">
</p>
* [GENCODE - Human Release](https://www.gencodegenes.org/human/)
Note: `count` is not very fast because it runs in a Ruby script.
This is fine in most cases, as long as the data size is small. If you want to visualize huge data, it is faster to use a combination of common Unix commands as shown below.
```sh
cat gencode.v35.annotation.gff3 | grep -v '#' | grep 'gene' | cut -f1 \
| sort | uniq -c | sort -nrk1 \
| uplot bar --fmt yx -d ' ' -t "The number of human gene annotations per chromosome" -c blue
```
## Usage
`uplot --help`
### Commands
`uplot` is the shortened form of `youplot`. You can use either.
| Command | Description |
|------------------------------------------------|-----------------------------------|
| `cat data.tsv \| uplot <command> [options]` | Take input from stdin |
| `uplot <command> [options] data.tsv ...` | Take input from files |
| `pipeline1 \| uplot <command> -O \| pipeline2` | Outputs data from stdin to stdout |
### Subcommands
The following sub-commands are available.
| command | short | how it works |
|-----------|-------|----------------------------------------|
| 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 |
| | | |
| count | c | draw a barplot based on the number of occurrences (slow) |
| | | |
| colors | color | show the list of available colors |
### Output the plot
* `-o`
* By default, the plot is output to **standard error output**.
* If you want to output to standard output, Use hyphen ` -o -` or no argument `uplot s -o | `.
### Output the input data
* `-O`
* By default, the input data is not shown anywhere.
* If you want to pass the input data directly to the standard output, Use hyphen `-O -` or no argument `uplot s -O |`.
* This is useful when passing data to a subsequent pipeline.
### Header
* `-H`
* If input data contains a header line, you need to specify the `-H` option.
### Delimiter
* `-d`
* You do not need to use `-d` option for tab-delimited text since the default value is tab.
* To specify a blank space, you can use `uplot bar -d ' ' data.txt`.
### Real-time data
* `-p` `--progress`
* Experimental progressive mode is currently under development.
* `ruby -e 'loop{puts rand(100)}' | uplot line --progress`
### Show detailed options for subcommands
* `--help`
* The `--help` option will show more detailed options for each subcommand.
* `uplot hist --help`
### Set columns as x-axis or y-axis
* YouPlot treats the first column as the X axis and the second column as the Y axis. When working with multiple series, the first column is the X axis, the second column is series Y1, the third column is series Y2, and so on.
* If you pass only one column of data for `line` and `bar`, YouPlot will automatically use a sequential number starting from 1 as the X-axis.
* `--fmt`
* `--fmt xyy` `--fmt xyxy` `--fmt yx` options give you a few more choices. See `youplot <command> --help` for more details.
* The fmt option may be renamed in the future.
* The `-x` and `-y` options might be used to specify columns in the future.
* Use `awk '{print $2, $1}'` to swap columns. Use `paste` to concatenate series.
### Categorical data
* With GNU datamash, you can manage to handle categorized data.
* `cat test/fixtures/iris.csv | sed '/^$/d' | datamash --header-in --output-delimiter=: -t, -g5 collapse 3,4 | cut -f2-3 -d: | sed 's/:/\n/g' | uplot s -d, -T --fmt xyxy`
* This is not so easy...
### Time series
* Not yet supported.
### YouPlot Configuration (youplotrc)
You can specify default options in a configuration file in YAML format. For more information, enter the following command.
```
Program: YouPlot (Tools for plotting on the terminal)
Version: 0.2.7 (using UnicodePlot 0.0.4)
Source: https://github.com/kojix2/youplot
Usage: uplot <command> [options] <in.tsv>
Commands:
barplot bar
histogram hist
lineplot line
lineplots lines
scatter s
density d
boxplot box
colors show the list of available colors
count c baplot based on the number of occurrences
(slower than `sort | uniq -c | sort -n -k1`)
Options:
-O, --pass [VAL] file to output standard input data to [stdout]
for inserting YouPlot in the middle of Unix pipes
-o, --output VAL file to output results to [stderr]
-d, --delimiter VAL use DELIM instead of TAB for field delimiter
-H, --headers specify that the input has header row
-T, --transpose transpose the axes of the input data
-t, --title VAL print string on the top of plot
-x, --xlabel VAL print string on the bottom of the plot
-y, --ylabel VAL print string on the far left of the plot
-w, --width VAL number of characters per row
-h, --height VAL number of rows
-b, --border VAL specify the style of the bounding box
-m, --margin VAL number of spaces to the left of the plot
-p, --padding VAL space of the left and right of the plot
-c, --color VAL color of the drawing
--[no-]labels hide the labels
--fmt VAL xyxy : header is like x1, y1, x2, y2, x3, y3...
xyy : header is like x, y1, y2, y2, y3...
uplot --config
```
Use `--help` to print command-specific options.
## Tools that are useful to use with YouPlot
`uplot hist --help`
```
Usage: uplot histogram [options] <in.tsv>
Options for histogram:
--symbol VAL character to be used to plot the bars
--closed VAL
-n, --nbins VAL approximate number of bins
Options:
...
```
## Development
Let's keep it simple.
* [csvtk](https://github.com/shenwei356/csvtk)
* [GNU datamash](https://www.gnu.org/software/datamash/)
* [awk](https://www.gnu.org/software/gawk/)
* [xsv](https://github.com/BurntSushi/xsv)
## Contributing
Bug reports and pull requests are welcome on GitHub at [https://github.com/kojix2/youplot](https://github.com/kojix2/youplot).
YouPlot is a library under development, so even small improvements like typofix are welcome!
Please feel free to send us your pull requests.
* [Report bugs](https://github.com/red-data-tools/YouPlot/issues)
* Fix bugs and [submit pull requests](https://github.com/red-data-tools/YouPlot/pulls)
* Write, clarify, or fix documentation
* English corrections by native speakers are welcome.
* Suggest or add new features
* Make a donation
### Development
```sh
# fork the main repository by clicking the Fork button.
git clone https://github.com/your_name/YouPlot
bundle install # Install the gem dependencies
bundle exec rake test # Run the test
bundle exec rake install # Installation from source code
bundle exec exe/uplot # Run youplot (Try out the edited code)
```
Do you need commit rights to my repository?
Do you want to get admin rights and take over the project?
If so, please feel free to contact us.
### Acknowledgements
* [sampo grafiikka](https://jypg.net/sampo_grafiikka) - Project logo creation
* [yutaas](https://github.com/yutaas) - English proofreading
## License

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

@ -1,9 +1,22 @@
# frozen_string_literal: true
require 'unicode_plot'
require 'youplot/version'
require 'youplot/dsv_reader'
require 'youplot/command'
require_relative 'youplot/version'
require_relative 'youplot/dsv'
require_relative 'youplot/parameters'
require_relative 'youplot/command'
module YouPlot
# @run_as_executable = true / false
# YouPlot behaves slightly differently when run as a command line tool
# and when run as a script (e.g. for testing). In the event of an error,
# when run as a command line tool, YouPlot will display a short error message
# and exit abnormally. When run as a script, it will just raise an error.
@run_as_executable = false
class << self
attr_accessor :run_as_executable
def run_as_executable?
@run_as_executable
end
end
end

View File

@ -6,18 +6,30 @@ module YouPlot
module Processing
module_function
def count_values(arr)
def count_values(arr, tally: true, reverse: false)
# tally was added in Ruby 2.7
if Enumerable.method_defined? :tally
result = \
if tally && Enumerable.method_defined?(:tally)
arr.tally
else
# https://github.com/marcandre/backports
arr.each_with_object(Hash.new(0)) { |item, res| res[item] += 1 }
.tap { |h| h.default = nil }
# value_counts Enumerable::Statistics
arr.value_counts(dropna: false)
end
.sort { |a, b| a[1] <=> b[1] }
.reverse
.transpose
# sorting
result = result.sort do |a, b|
# compare values
r = b[1] <=> a[1]
# If the values are the same, compare by name
r = a[0] <=> b[0] if r.zero?
r
end
# --reverse option
result.reverse! if reverse
# prepare for barplot
result.transpose
end
end
end

View File

@ -1,20 +1,46 @@
# frozen_string_literal: true
# UnicodePlot - Plot your data by Unicode characters
# https://github.com/red-data-tools/unicode_plot.rb
require_relative 'processing'
require 'unicode_plot'
# If the line color is specified as a number, the program will display an error
# message to the user and exit. Remove this patch when UnicodePlot is improved.
module UnicodePlot
class << self
alias lineplot_original lineplot
def lineplot(*args, **kw)
if kw[:color].is_a? Numeric
warn <<~EOS
YouPlot: Line colors cannot be specified by numerical values.
For more information, please see the following issue.
https://github.com/red-data-tools/unicode_plot.rb/issues/34
EOS
YouPlot.run_as_executable ? exit(1) : raise(Error)
end
lineplot_original(*args, **kw)
end
end
end
module YouPlot
# plotting functions.
module Backends
module UnicodePlotBackend
module UnicodePlot
class Error < StandardError; end
module_function
def barplot(data, params, fmt = nil, count: false)
def barplot(data, params, fmt = nil, count: false, reverse: false)
headers = data.headers
series = data.series
# `uplot count`
if count
series = Processing.count_values(series[0])
series = Processing.count_values(series[0], reverse: reverse)
params.title = headers[0] if headers
end
if series.size == 1
@ -37,7 +63,7 @@ module YouPlot
labels = series[x_col]
values = series[y_col].map(&:to_f)
end
UnicodePlot.barplot(labels, values, **params.to_hc)
::UnicodePlot.barplot(labels, values, **params.to_hc)
end
def histogram(data, params)
@ -45,7 +71,7 @@ module YouPlot
series = data.series
params.title ||= data.headers[0] if headers
values = series[0].map(&:to_f)
UnicodePlot.histogram(values, **params.to_hc)
::UnicodePlot.histogram(values, **params.to_hc)
end
def line(data, params, fmt = nil)
@ -55,7 +81,7 @@ module YouPlot
# If there is only one series, it is assumed to be sequential data.
params.ylabel ||= headers[0] if headers
y = series[0].map(&:to_f)
UnicodePlot.lineplot(y, **params.to_hc)
::UnicodePlot.lineplot(y, **params.to_hc)
else
# If there are 2 or more series...
if fmt == 'yx'
@ -73,7 +99,7 @@ module YouPlot
end
x = series[x_col].map(&:to_f)
y = series[y_col].map(&:to_f)
UnicodePlot.lineplot(x, y, **params.to_hc)
::UnicodePlot.lineplot(x, y, **params.to_hc)
end
end
@ -90,27 +116,28 @@ 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)
plot = ::UnicodePlot.public_send(method1, series[0], series[1], **params.to_hc)
2.upto(series.size - 1) do |i|
UnicodePlot.public_send(method2, plot, series[0], series[i], name: headers&.[](i))
::UnicodePlot.public_send(method2, plot, series[0], series[i], name: headers&.[](i))
end
plot
end
def plot_xyxy(data, method1, params)
headers = data.headers
series = data.series
series2 = data.series
.map { |s| s.map(&:to_f) }
.each_slice(2).to_a
method2 = get_method2(method1)
series.map! { |s| s.map(&:to_f) }
series = series.each_slice(2).to_a
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
plot = UnicodePlot.public_send(method1, x1, y1, **params.to_hc)
series.each_with_index do |(xi, yi), i|
UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
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)
series2.each_with_index do |(xi, yi), i|
::UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
end
plot
end
@ -148,39 +175,51 @@ module YouPlot
series = data.series
headers ||= (1..series.size).map(&:to_s)
series.map! { |s| s.map(&:to_f) }
UnicodePlot.boxplot(headers, series, **params.to_hc)
::UnicodePlot.boxplot(headers, series, **params.to_hc)
end
def colors(color_names = false)
UnicodePlot::StyledPrinter::TEXT_COLORS.each do |k, v|
print v
print k
# FIXME
s = String.new
::UnicodePlot::StyledPrinter::TEXT_COLORS.each do |k, v|
s << v
s << k.to_s
unless color_names
print "\t"
print ' ●'
s << "\t"
s << ' ●'
end
print "\033[0m"
print "\t"
s << "\033[0m"
s << "\t"
end
puts
s << "\n"
def s.render(obj)
obj.print(self)
end
s
end
def check_series_size(data, fmt)
series = data.series
if series.size == 1
warn 'youplot: There is only one series of input data. Please check the delimiter.'
warn ''
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
warn <<~EOS
YouPlot: There is only one series of input data. Please check the delimiter.
Headers: \e[35m#{data.headers.inspect}\e[0m
The first item is: \e[35m\"#{series[0][0]}\"\e[0m
The last item is : \e[35m\"#{series[0][-1]}\"\e[0m
EOS
# NOTE: Error messages cannot be colored.
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
warn <<~EOS
YouPlot: In the xyxy format, the number of series must be even.
Number of series: \e[35m#{series.size}\e[0m
Headers: \e[35m#{data.headers.inspect}\e[0m
EOS
# NOTE: Error messages cannot be colored.
YouPlot.run_as_executable ? exit(1) : raise(Error)
end
end
end

View File

@ -1,97 +1,227 @@
# frozen_string_literal: true
require_relative 'dsv_reader'
require_relative 'command/parser'
require_relative 'dsv'
require_relative 'parser'
# FIXME
require_relative 'backends/unicode_plot_backend'
require_relative 'backends/unicode_plot'
module YouPlot
Data = Struct.new(:headers, :series)
class Command
attr_accessor :params
attr_reader :data, :fmt, :parser
attr_accessor :command, :params, :options
attr_reader :data, :parser
def initialize(argv = ARGV)
@argv = argv
@params = Params.new
@parser = Parser.new
@backend = YouPlot::Backends::UnicodePlotBackend
@command = nil
@params = nil
@options = nil
@backend = YouPlot::Backends::UnicodePlot
end
def run_as_executable
YouPlot.run_as_executable = true
run
end
def run
parser.parse_options(@argv)
command = parser.command
params = parser.params
delimiter = parser.delimiter
transpose = parser.transpose
headers = parser.headers
pass = parser.pass
output = parser.output
fmt = parser.fmt
@encoding = parser.encoding
@debug = parser.debug
@command ||= parser.command
@options ||= parser.options
@params ||= parser.params
if command == :colors
@backend.colors(parser.color_names)
exit
# color command
if %i[colors color colours colour].include? @command
plot = create_plot
output_plot(plot)
return
end
# Sometimes the input file does not end with a newline code.
while (input = Kernel.gets(nil))
# progressive mode
if options[:progressive]
stop = false
Signal.trap(:INT) { stop = true }
# Pass the input to subsequent pipelines
case pass
when IO
pass.print(input)
# make cursor invisible
options[:output].print "\e[?25l"
# mainloop
while (input = Kernel.gets)
n = main_progressive(input)
break if stop
options[:output].print "\e[#{n}F"
end
options[:output].print "\e[0J"
# make cursor visible
options[:output].print "\e[?25h"
# normal mode
else
if pass
File.open(pass, 'w') do |f|
# Sometimes the input file does not end with a newline code.
begin
begin
input = Kernel.gets(nil)
rescue Errno::ENOENT => e
warn e.message
next
end
main(input)
end until input
end
end
private
def main(input)
# Outputs input data to a file or stdout.
output_data(input)
@data = parse_dsv(input)
# Debug mode, show parsed results
pp @data if options[:debug]
# When run as a program instead of a library
if YouPlot.run_as_executable?
begin
plot = create_plot
rescue ArgumentError => e
# Show only one line of error.
warn e.backtrace[0]
# Show error message in purple
warn "\e[35m#{e}\e[0m"
# Explicitly terminated with exit code: 1
exit 1
end
# When running YouPlot as a library (e.g. for testing)
else
plot = create_plot
end
output_plot(plot)
end
def main_progressive(input)
output_data(input)
# FIXME
# Worked around the problem of not being able to draw
# plots when there is only one header line.
if @raw_data.nil?
@raw_data = String.new
if options[:headers]
@raw_data << input
return
end
end
@raw_data << input
# FIXME
@data = parse_dsv(@raw_data)
plot = create_plot
output_plot_progressive(plot)
end
def parse_dsv(input)
# If encoding is specified, convert to UTF-8
if options[:encoding]
input.force_encoding(options[:encoding])
.encode!('utf-8')
end
begin
data = DSV.parse(input, options[:delimiter], options[:headers], options[:transpose])
rescue CSV::MalformedCSVError => e
warn 'Failed to parse the text. '
warn 'Please try to set the correct character encoding with --encoding option.'
warn e.backtrace.grep(/youplot/).first
exit 1
rescue ArgumentError => e
warn 'Failed to parse the text. '
warn e.backtrace.grep(/youplot/).first
exit 1
end
data
end
def create_plot
case command
when :bar, :barplot
@backend.barplot(data, params, options[:fmt])
when :count, :c
@backend.barplot(data, params, count: true, reverse: options[:reverse])
when :hist, :histogram
@backend.histogram(data, params)
when :line, :lineplot, :l
@backend.line(data, params, options[:fmt])
when :lines, :lineplots, :ls
@backend.lines(data, params, options[:fmt])
when :scatter, :s
@backend.scatter(data, params, options[:fmt])
when :density, :d
@backend.density(data, params, options[:fmt])
when :box, :boxplot
@backend.boxplot(data, params)
when :colors, :color, :colours, :colour
@backend.colors(options[:color_names])
else
raise "unrecognized plot_type: #{command}"
end
end
def output_data(input)
# Pass the input to subsequent pipelines
case options[:pass]
when IO, StringIO
options[:pass].print(input)
else
if options[:pass]
File.open(options[:pass], 'w') do |f|
f.print(input)
end
end
end
@data = if @encoding
input2 = input.dup.force_encoding(@encoding).encode('utf-8')
DSVReader.input(input2, delimiter, headers, transpose)
else
DSVReader.input(input, delimiter, headers, transpose)
end
pp @data if @debug
plot = case command
when :bar, :barplot
@backend.barplot(data, params, fmt)
when :count, :c
@backend.barplot(data, params, count: true)
when :hist, :histogram
@backend.histogram(data, params)
when :line, :lineplot
@backend.line(data, params, fmt)
when :lines, :lineplots
@backend.lines(data, params, fmt)
when :scatter, :s
@backend.scatter(data, params, fmt)
when :density, :d
@backend.density(data, params, fmt)
when :box, :boxplot
@backend.boxplot(data, params)
else
raise "unrecognized plot_type: #{command}"
end
case output
when IO
plot.render(output)
else
File.open(output, 'w') do |f|
def output_plot(plot)
case options[:output]
when IO, StringIO
plot.render(options[:output])
when String, Tempfile
File.open(options[:output], 'w') do |f|
plot.render(f)
end
end
end
def output_plot_progressive(plot)
case options[:output]
when IO, StringIO
# RefactorMe
out = StringIO.new(String.new)
def out.tty?
true
end
plot.render(out)
lines = out.string.lines
lines.each do |line|
options[:output].print line.chomp
options[:output].print "\e[0K"
options[:output].puts
end
options[:output].print "\e[0J"
options[:output].flush
out.string.lines.size
else
raise 'In progressive mode, output to a file is not possible.'
end
end
end

View File

@ -1,37 +0,0 @@
# frozen_string_literal: true
module YouPlot
class Command
# UnicodePlot parameters.
# * Normally in a Ruby program, you might use hash for the parameter object.
# * Here, I use Struct for 2 safety reason.
# * The keys are static in Struct.
# * Struct does not conflict with keyword arguments. Hash dose.
Params = Struct.new(
# Sort me!
:title,
:width,
:height,
:border,
:margin,
:padding,
:color,
:xlabel,
:ylabel,
:labels,
:symbol,
:xscale,
:nbins,
:closed,
:canvas,
:xlim,
:ylim,
:grid,
:name
) do
def to_hc
to_h.compact
end
end
end
end

View File

@ -1,277 +0,0 @@
# frozen_string_literal: true
require 'optparse'
require_relative 'params'
module YouPlot
class Command
class Parser
attr_reader :command, :params,
:delimiter, :transpose, :headers, :pass, :output, :fmt,
:color_names, :encoding, :debug
def initialize
@command = nil
@params = Params.new
@delimiter = "\t"
@transpose = false
@headers = nil
@pass = false
@output = $stderr
@fmt = 'xyy'
@encoding = nil
@debug = false
@color_names = false
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 [VAL]', 'file to output standard input data to [stdout]',
'for inserting YouPlot in the middle of Unix pipes') do |v|
@pass = v || $stdout
end
opt.on('-o', '--output VAL', 'file to output results to [stderr]') do |v|
@output = v
end
opt.on('-d', '--delimiter VAL', String, 'use DELIM instead of TAB for field delimiter') do |v|
@delimiter = v
end
opt.on('-H', '--headers', TrueClass, 'specify that the input has header row') do |v|
@headers = v
end
opt.on('-T', '--transpose', TrueClass, 'transpose the axes of the input data') do |v|
@transpose = v
end
opt.on('-t', '--title VAL', 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|
params.xlabel = v
end
opt.on('-y', '--ylabel VAL', 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|
params.width = v
end
opt.on('-h', '--height VAL', 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|
params.border = v.to_sym
end
opt.on('-m', '--margin VAL', 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|
params.padding = v
end
opt.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|
params.labels = v
end
opt.on('--encoding VAL', String, 'Specify the input encoding') do |v|
@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
end
opt.on('--debug', TrueClass, 'print preprocessed data') do |v|
@debug = v
end
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
Usage: uplot <command> [options] <in.tsv>
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 show the list of available colors
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
# 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
end
end
def sub_parser
@sub_parser ||= create_default_parser do |parser|
parser.banner = <<~MSG
Usage: YouPlot #{command} [options] <in.tsv>
Options for #{command}:
MSG
case command
# If you type only `uplot` in the terminal.
when nil
warn main_parser.banner
warn "\n"
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|
@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|
@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|
@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|
@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|
@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
parser.on_head('-n', '--names', 'show color names only', TrueClass) do |v|
@color_names = v
end
else
warn "uplot: unrecognized command '#{command}'"
exit 1
end
end
end
def parse_options(argv = ARGV)
begin
main_parser.order!(argv)
rescue OptionParser::ParseError => e
warn "uplot: #{e.message}"
exit 1
end
@command = argv.shift&.to_sym
begin
sub_parser.parse!(argv)
rescue OptionParser::ParseError => e
warn "uplot: #{e.message}"
exit 1
end
end
end
end
end

87
lib/youplot/dsv.rb Normal file
View File

@ -0,0 +1,87 @@
# frozen_string_literal: true
require 'csv'
module YouPlot
# Module to handle DSV (Delimiter-separated values) format.
# Extract header and series.
module DSV
module_function
def parse(input, delimiter, headers, transpose)
# Parse as CSV
arr = CSV.parse(input, col_sep: delimiter)
# Remove blank lines
arr.delete_if do |i|
i == [] or i.all?(&:nil?)
end
# get header
headers = get_headers(arr, headers, transpose)
# get series
series = get_series(arr, headers, transpose)
# Return if No header
return Data.new(headers, series) if headers.nil?
# Warn if header contains nil
warn "\e[35mHeaders contains nil in it.\e[0m" if headers.include?(nil)
# Warn if header contains ''
warn "\e[35mHeaders contains \"\" in it.\e[0m" if headers.include? ''
# Make sure the number of elements in the header matches the number of series.
h_size = headers.size
s_size = series.size
if h_size > s_size
warn "\e[35mThe number of headers is greater than the number of series.\e[0m"
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 if YouPlot.run_as_executable?
end
Data.new(headers, series) if h_size == s_size
end
# Transpose different sized ruby arrays
# https://stackoverflow.com/q/26016632
def transpose2(arr)
Array.new(arr.map(&:length).max) { |i| arr.map { |e| e[i] } }
end
def get_headers(arr, headers, transpose)
# header(-)
return nil unless headers
# header(+) trenspose(+)
return arr.map(&:first) if transpose
# header(+) transpose(-)
arr[0]
end
def get_series(arr, headers, transpose)
# header(-)
unless headers
return arr if transpose
return transpose2(arr)
end
# header(+) but no element in the series.
# TODO: should raise error?
return Array.new(arr[0].size, []) if arr.size == 1
# header(+) transpose(+)
return arr.map { |row| row[1..-1] } if transpose
# header(+) transpose(-)
transpose2(arr[1..-1])
end
end
end

View File

@ -1,73 +0,0 @@
# frozen_string_literal: true
require 'csv'
module YouPlot
# Read and interpret Delimiter-separated values format file or stream.
module DSVReader
module_function
def input(input, delimiter, headers, transpose)
arr = parse_as_csv(input, delimiter)
headers = get_headers(arr, headers, transpose)
series = get_series(arr, headers, transpose)
if headers.nil?
Data.new(headers, series)
else
if headers.include?(nil)
warn "\e[35mHeaders contains nil in it.\e[0m"
elsif headers.include? ''
warn "\e[35mHeaders contains \"\" in it.\e[0m"
end
h_size = headers.size
s_size = series.size
if h_size == s_size
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
elsif h_size < s_size
warn "\e[35mThe number of headers is less than the number of series.\e[0m"
exit 1
end
end
end
def parse_as_csv(input, delimiter)
CSV.parse(input, col_sep: delimiter)
.delete_if do |i|
i == [] or i.all? nil
end
end
# Transpose different sized ruby arrays
# https://stackoverflow.com/q/26016632
def transpose2(arr)
Array.new(arr.map(&:length).max) { |i| arr.map { |e| e[i] } }
end
def get_headers(arr, headers, transpose)
if headers
if transpose
arr.map(&:first)
else
arr[0]
end
end
end
def get_series(arr, headers, transpose)
if transpose
if headers
arr.map { |row| row[1..-1] }
else
arr
end
elsif headers
transpose2(arr[1..-1])
else
transpose2(arr)
end
end
end
end

18
lib/youplot/options.rb Normal file
View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
module YouPlot
# Command line options that are not Plot parameters
Options = Struct.new(
:delimiter,
:transpose,
:headers,
:pass,
:output,
:fmt,
:progressive,
:encoding,
:reverse, # count
:color_names, # color
:debug
)
end

34
lib/youplot/parameters.rb Normal file
View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
module YouPlot
# UnicodePlot parameters.
# Why Struct, not Hash?
# * The keys are static in Struct.
# * Struct does not conflict with keyword arguments. Hash dose.
Parameters = Struct.new(
# Sort me!
:title,
:width,
:height,
:border,
:margin,
:padding,
:color,
:xlabel,
:ylabel,
:labels,
:symbol,
:xscale,
:nbins,
:closed,
:canvas,
:xlim,
:ylim,
:grid,
:name
) do
def to_hc
to_h.compact
end
end
end

410
lib/youplot/parser.rb Normal file
View File

@ -0,0 +1,410 @@
# frozen_string_literal: true
require 'optparse'
require_relative 'options'
module YouPlot
# Class for parsing command line options
class Parser
class Error < StandardError; end
attr_reader :command, :options, :params,
:main_parser, :sub_parser,
:config_file, :config
def initialize
@command = nil
@options = Options.new(
"\t", # elimiter:
false, # transpose:
nil, # headers:
false, # pass:
$stderr, # output:
'xyy', # fmt:
false, # progressive:
nil, # encoding:
false, # color_names:
false # debug:
)
@params = Parameters.new
end
def apply_config_file
return if !config_file && find_config_file.nil?
read_config_file
configure
end
def config_file_candidate_paths
# keep the order of the paths
paths = []
paths << ENV['MYYOUPLOTRC'] if ENV['MYYOUPLOTRC']
paths << '.youplot.yml'
paths << '.youplotrc'
if ENV['HOME']
paths << File.join(ENV['HOME'], '.youplotrc')
paths << File.join(ENV['HOME'], '.youplot.yml')
paths << File.join(ENV['HOME'], '.config', 'youplot', 'youplotrc')
paths << File.join(ENV['HOME'], '.config', 'youplot', 'youplot.yml')
end
paths
end
def find_config_file
config_file_candidate_paths.each do |file|
path = File.expand_path(file)
next unless File.exist?(path)
@config_file = path
ENV['MYYOUPLOTRC'] = path
return @config_file
end
nil
end
def read_config_file
require 'yaml'
@config = YAML.load_file(config_file)
end
def configure
option_members = @options.members
param_members = @params.members
# It would be more useful to be able to configure by plot type
config.each do |k, v|
k = k.to_sym
if option_members.include?(k)
@options[k] ||= v
elsif param_members.include?(k)
@params[k] ||= v
else
raise Error, "Unknown option/param in config file: #{k}"
end
end
end
def create_base_parser
OptionParser.new do |parser|
parser.program_name = 'YouPlot'
parser.version = YouPlot::VERSION
parser.summary_width = 23
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
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
parser.on('-d', '--delimiter DELIM', String, 'use DELIM instead of [TAB] for field delimiter') do |v|
options[:delimiter] = v
end
parser.on('-H', '--headers', TrueClass, 'specify that the input has header row') do |v|
options[:headers] = v
end
parser.on('-T', '--transpose', TrueClass, 'transpose the axes of the input data') do |v|
options[:transpose] = v
end
parser.on('-t', '--title STR', String, 'print string on the top of plot') do |v|
params.title = v
end
parser.on('--xlabel STR', String, 'print string on the bottom of the plot') do |v|
params.xlabel = v
end
parser.on('--ylabel STR', String, 'print string on the far left of the plot') do |v|
params.ylabel = v
end
parser.on('-w', '--width INT', Numeric, 'number of characters per row') do |v|
params.width = v
end
parser.on('-h', '--height INT', Numeric, 'number of rows') do |v|
params.height = v
end
border_options = UnicodePlot::BORDER_MAP.keys.join(', ')
parser.on('-b', '--border STR', String, 'specify the style of the bounding box', "(#{border_options})") do |v|
params.border = v.to_sym
end
parser.on('-m', '--margin INT', Numeric, 'number of spaces to the left of the plot') do |v|
params.margin = v
end
parser.on('--padding INT', Numeric, 'space of the left and right of the plot') do |v|
params.padding = v
end
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
parser.on('--[no-]labels', TrueClass, 'hide the labels') do |v|
params.labels = v
end
parser.on('-p', '--progress', TrueClass, 'progressive mode [experimental]') do |v|
options[:progressive] = v
end
parser.on('-C', '--color-output', TrueClass, 'colorize even if writing to a pipe') do |_v|
UnicodePlot::IOContext.define_method(:color?) { true } # FIXME
end
parser.on('-M', '--monochrome', TrueClass, 'no colouring even if writing to a tty') do |_v|
UnicodePlot::IOContext.define_method(:color?) { false } # FIXME
end
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.
parser.on('--help', 'print sub-command help menu') do
puts parser.help
exit if YouPlot.run_as_executable?
end
parser.on('--config FILE', 'specify a config file') do |v|
@config_file = v
end
parser.on('--debug', TrueClass, 'print preprocessed data') do |v|
options[:debug] = v
end
# yield opt if block_given?
end
end
def create_main_parser
@main_parser = create_base_parser
main_parser.banner = \
<<~MSG
Program: YouPlot (Tools for plotting on the terminal)
Version: #{YouPlot::VERSION} (using UnicodePlot #{UnicodePlot::VERSION})
Source: https://github.com/red-data-tools/YouPlot
Usage: uplot <command> [options] <in.tsv>
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
count c draw a barplot based on the number of
occurrences (slow)
colors color show the list of available colors
General options:
--config print config file info
--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
show_main_help
end
main_parser.on('--config', 'show config file info') do
show_config_info
end
end
def show_main_help(out = $stdout)
out.puts main_parser.banner
out.puts
exit if YouPlot.run_as_executable?
end
def show_config_info
if ENV['MYYOUPLOTRC']
puts "config file : #{ENV['MYYOUPLOTRC']}"
puts config.inspect
else
puts <<~EOS
Configuration file not found.
It should be a YAML file, like this example:
width : 40
height : 20
By default, YouPlot will look for the configuration file in these locations:
#{config_file_candidate_paths.map { |s| ' ' + s }.join("\n")}
If you have the file elsewhere, you can specify its location with the `MYYOUPLOTRC` environment variable.
EOS
end
exit if YouPlot.run_as_executable?
end
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.to_sym
end
end
def sub_parser_add_canvas
canvas_types = UnicodePlot::Canvas::CANVAS_CLASS_MAP.keys.join(', ')
sub_parser.on_head('--canvas STR', String, 'type of canvas', "(#{canvas_types})") 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.map(&:to_f)
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.map(&:to_f)
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 sub_parser_add_fmt_xyxy
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
end
def sub_parser_add_fmt_yx
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
end
def create_sub_parser
@sub_parser = create_base_parser
sub_parser.banner = \
<<~MSG
Usage: YouPlot #{command} [options] <in.tsv>
Options for #{command}:
MSG
case command
# If you type only `uplot` in the terminal.
# Output help to standard error output.
when nil
show_main_help($stderr)
# Output help to standard output.
when :help
show_main_help
when :barplot, :bar
sub_parser_add_symbol
sub_parser_add_fmt_yx
sub_parser_add_xscale
when :count, :c
sub_parser.on_head('-r', '--reverse', TrueClass, 'reverse the result of comparisons') do |v|
options.reverse = v
end
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, :l
sub_parser_add_canvas
sub_parser_add_grid
sub_parser_add_fmt_yx
sub_parser_add_ylim
sub_parser_add_xlim
when :lineplots, :lines, :ls
sub_parser_add_canvas
sub_parser_add_grid
sub_parser_add_fmt_xyxy
sub_parser_add_ylim
sub_parser_add_xlim
when :scatter, :s
sub_parser_add_canvas
sub_parser_add_grid
sub_parser_add_fmt_xyxy
sub_parser_add_ylim
sub_parser_add_xlim
when :density, :d
sub_parser_add_canvas
sub_parser_add_grid
sub_parser_add_fmt_xyxy
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', TrueClass, 'show color names only') do |v|
options[:color_names] = v
end
# Currently it simply displays the configuration file,
# but in the future this may be changed to open a text editor like Vim
# to edit the configuration file.
when :config
show_config_info
else
error_message = "YouPlot: unrecognized command '#{command}'"
raise Error, error_message unless YouPlot.run_as_executable?
warn error_message
exit 1
end
end
def parse_options(argv = ARGV)
begin
create_main_parser.order!(argv)
rescue OptionParser::ParseError => e
warn "YouPlot: #{e.message}"
exit 1 if YouPlot.run_as_executable?
end
@command = argv.shift&.to_sym
begin
create_sub_parser&.parse!(argv)
rescue OptionParser::ParseError => e
warn "YouPlot: #{e.message}"
exit 1 if YouPlot.run_as_executable?
end
begin
apply_config_file
rescue StandardError => e
warn "YouPlot: #{e.message}"
exit 1 if YouPlot.run_as_executable?
end
end
end
end

View File

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

319
logo.svg Normal file
View File

@ -0,0 +1,319 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="162mm" height="56mm" version="1.1" viewBox="0 0 162 56" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="linearGradient1606" x2="1" gradientTransform="matrix(0 -72.481 -72.481 0 969.69 413.89)" gradientUnits="userSpaceOnUse">
<stop stop-color="#93d4f5" offset="0"/>
<stop stop-color="#93d4f5" offset=".00021973"/>
<stop stop-color="#93d4f5" offset=".69201"/>
<stop stop-color="#2f98be" offset="1"/>
</linearGradient>
<clipPath id="clipPath1616">
<path d="m0 1481.2h1762.6v-1481.2h-1762.6z"/>
</clipPath>
<linearGradient id="linearGradient1642" x2="1" gradientTransform="matrix(0 -55.11 -55.11 0 1004 402.52)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34a2cb" offset="0"/>
<stop stop-color="#7acdf4" offset=".4661"/>
<stop stop-color="#7acdf4" offset=".65419"/>
<stop stop-color="#34a2cb" offset="1"/>
</linearGradient>
<clipPath id="clipPath1652">
<path d="m0 1481.2h1762.6v-1481.2h-1762.6z"/>
</clipPath>
<linearGradient id="linearGradient1694" x2="1" gradientTransform="matrix(0 -72.481 72.481 0 1353.9 413.89)" gradientUnits="userSpaceOnUse">
<stop stop-color="#93d4f5" offset="0"/>
<stop stop-color="#93d4f5" offset=".00021973"/>
<stop stop-color="#93d4f5" offset=".69201"/>
<stop stop-color="#2f98be" offset="1"/>
</linearGradient>
<clipPath id="clipPath1704">
<path d="m0 1481.2h1762.6v-1481.2h-1762.6z"/>
</clipPath>
<linearGradient id="linearGradient1730" x2="1" gradientTransform="matrix(0 -55.11 55.11 0 1319.6 402.52)" gradientUnits="userSpaceOnUse">
<stop stop-color="#34a2cb" offset="0"/>
<stop stop-color="#7acdf4" offset=".4661"/>
<stop stop-color="#7acdf4" offset=".65419"/>
<stop stop-color="#34a2cb" offset="1"/>
</linearGradient>
<clipPath id="clipPath1740">
<path d="m0 1481.2h1762.6v-1481.2h-1762.6z"/>
</clipPath>
</defs>
<g>
<g transform="translate(-25.939 -54.31)">
<g transform="matrix(.35278 0 0 -.35278 51.305 83.317)">
<path d="m0 0c-7.809 0-14.162-16.346-14.162-36.439 0-20.094 6.353-36.44 14.162-36.44 7.81 0 14.163 16.346 14.163 36.44 0 20.093-6.353 36.439-14.163 36.439m0-73.872c-8.498 0-15.155 16.442-15.155 37.433 0 20.99 6.657 37.432 15.155 37.432 8.499 0 15.155-16.442 15.155-37.432 0-20.991-6.656-37.433-15.155-37.433" fill="#fff"/>
</g>
<g transform="matrix(.35278 0 0 -.35278 46.133 96.173)">
<path d="m0 0c0-20.398 6.563-36.936 14.659-36.936 8.097 0 14.66 16.538 14.66 36.936 0 20.399-6.563 36.937-14.66 36.937-8.096 0-14.659-16.538-14.659-36.937" fill="#71bde1"/>
</g>
<g transform="matrix(.35278 0 0 -.35278 51.305 83.317)">
<path d="m0 0c-7.809 0-14.162-16.346-14.162-36.439 0-20.094 6.353-36.44 14.162-36.44 7.81 0 14.163 16.346 14.163 36.44 0 20.093-6.353 36.439-14.163 36.439m0-73.872c-8.498 0-15.155 16.442-15.155 37.433 0 20.99 6.657 37.432 15.155 37.432 8.499 0 15.155-16.442 15.155-37.432 0-20.991-6.656-37.433-15.155-37.433" fill="#fff"/>
</g>
<g transform="matrix(.35278 0 0 -.35278 51.305 109.38)">
<path d="m0 0h-53.903c-8.499 0-15.156 16.442-15.156 37.433 0 20.64 6.799 37.432 15.156 37.432h53.903v-0.993h-53.903c-7.81 0-14.163-16.346-14.163-36.439 0-20.094 6.353-36.44 14.163-36.44h53.903z" fill="#fff"/>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g>
<g>
<g>
<path d="m950.06 414.45c-8.095 0-14.659-16.538-14.659-36.937s6.564-36.935 14.659-36.935h53.904c-8.096 0-14.659 16.536-14.659 36.935s6.563 36.937 14.659 36.937z" fill="url(#linearGradient1606)"/>
</g>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g clip-path="url(#clipPath1616)">
<g transform="translate(950.07 413.95)">
<path d="m0 0c-7.81 0-14.163-16.346-14.163-36.439 0-20.094 6.353-36.44 14.163-36.44h50.354c-6.732 3.849-11.606 18.481-11.606 36.44s4.874 32.59 11.606 36.439zm53.903-73.872h-53.903c-8.499 0-15.155 16.442-15.155 37.433 0 20.64 6.799 37.432 15.155 37.432h53.903v-0.993c-7.808 0-14.162-16.346-14.162-36.439 0-20.094 6.354-36.44 14.162-36.44z" fill="#fff"/>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g>
<g>
<g>
<path d="m994.28 377.51c0-16.982 4.34-30.748 9.694-30.748 5.353 0 9.693 13.766 9.693 30.748 0 16.984-4.34 30.75-9.693 30.75-5.354 0-9.694-13.766-9.694-30.75" fill="url(#linearGradient1642)"/>
</g>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g clip-path="url(#clipPath1652)">
<g transform="translate(1004 407.77)">
<path d="m0 0c-4.985 0-9.196-13.854-9.196-30.253s4.211-30.255 9.196-30.255c4.986 0 9.197 13.856 9.197 30.255s-4.211 30.253-9.197 30.253m0-61.5c-5.713 0-10.189 13.726-10.189 31.247s4.476 31.246 10.189 31.246c5.714 0 10.19-13.725 10.19-31.246s-4.476-31.247-10.19-31.247" fill="#fff"/>
</g>
<g transform="translate(1319.6 413.95)">
<path d="m0 0c-7.811 0-14.164-16.346-14.164-36.439 0-20.094 6.353-36.44 14.164-36.44 7.81 0 14.163 16.346 14.163 36.44 0 20.093-6.353 36.439-14.163 36.439m0-73.872c-8.498 0-15.156 16.442-15.156 37.433 0 20.99 6.658 37.432 15.156 37.432 8.499 0 15.155-16.442 15.155-37.432 0-20.991-6.656-37.433-15.155-37.433" fill="#fff"/>
</g>
<g transform="translate(1334.2 377.51)">
<path d="m0 0c0-20.398-6.563-36.936-14.659-36.936-8.097 0-14.659 16.538-14.659 36.936 0 20.399 6.562 36.937 14.659 36.937 8.096 0 14.659-16.538 14.659-36.937" fill="#71bde1"/>
</g>
<g transform="translate(1319.6 413.95)">
<path d="m0 0c-7.811 0-14.164-16.346-14.164-36.439 0-20.094 6.353-36.44 14.164-36.44 7.81 0 14.163 16.346 14.163 36.44 0 20.093-6.353 36.439-14.163 36.439m0-73.872c-8.498 0-15.156 16.442-15.156 37.433 0 20.99 6.658 37.432 15.156 37.432 8.499 0 15.155-16.442 15.155-37.432 0-20.991-6.656-37.433-15.155-37.433" fill="#fff"/>
</g>
<g transform="translate(1373.5 340.08)">
<path d="m0 0h-53.903v0.993h53.903c7.811 0 14.164 16.346 14.164 36.44 0 20.093-6.353 36.439-14.164 36.439h-53.903v0.993h53.903c8.498 0 15.156-16.442 15.156-37.432 0-20.991-6.658-37.433-15.156-37.433" fill="#fff"/>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g>
<g>
<g>
<path d="m1319.6 414.45c8.096 0 14.659-16.538 14.659-36.937s-6.563-36.935-14.659-36.935h53.903c8.097 0 14.66 16.536 14.66 36.935s-6.563 36.937-14.66 36.937z" fill="url(#linearGradient1694)"/>
</g>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g clip-path="url(#clipPath1704)">
<g transform="translate(1323.1 341.08)">
<path d="m0 0h50.353c7.81 0 14.164 16.346 14.164 36.439 0 20.094-6.354 36.44-14.164 36.44h-50.353c6.73-3.849 11.604-18.481 11.604-36.44s-4.874-32.59-11.604-36.439m50.353-0.993h-53.904v0.993c7.81 0 14.163 16.346 14.163 36.439 0 20.094-6.353 36.44-14.163 36.44v0.993h53.904c8.498 0 15.156-16.442 15.156-37.433 0-20.99-6.658-37.432-15.156-37.432" fill="#fff"/>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g>
<g>
<g>
<path d="m1309.9 377.51c0-16.982 4.34-30.748 9.693-30.748 5.354 0 9.694 13.766 9.694 30.748 0 16.984-4.34 30.75-9.694 30.75-5.353 0-9.693-13.766-9.693-30.75" fill="url(#linearGradient1730)"/>
</g>
</g>
</g>
</g>
<g transform="matrix(.35278 0 0 -.35278 -302.87 229.35)">
<g clip-path="url(#clipPath1740)">
<g transform="translate(1319.6 407.77)">
<path d="m0 0c-4.986 0-9.197-13.854-9.197-30.253s4.211-30.255 9.197-30.255 9.197 13.856 9.197 30.255-4.211 30.253-9.197 30.253m0-61.5c-5.713 0-10.189 13.726-10.189 31.247s4.476 31.246 10.189 31.246c5.714 0 10.189-13.725 10.189-31.246s-4.475-31.247-10.189-31.247" fill="#fff"/>
</g>
<g transform="translate(1066.3 377.51)">
<path d="m0 0-15.355 8.867v-3.637h-22.405v-10.459h22.405v-3.637z" fill="#55c3f1"/>
</g>
<g transform="translate(1295.9 377.51)">
<path d="m0 0-15.355 8.867v-3.637h-22.405v-10.459h22.405v-3.637z" fill="#55c3f1"/>
</g>
<g transform="translate(1111.3 380.14)">
<path d="m0 0h6.173l-12.187-16.271-2.068-9.797h-5.448l2.069 9.797-5.554 16.271h6.421l2.99-11.354z" fill="#0071be"/>
</g>
<g transform="translate(1129.9 363.68)">
<path d="m0 0c0.414 1.936 0.334 3.424-0.238 4.467-0.573 1.043-1.595 1.566-3.07 1.566-1.473 0-2.716-0.523-3.731-1.566s-1.728-2.531-2.141-4.467c-0.412-1.933-0.332-3.426 0.24-4.474 0.571-1.048 1.595-1.574 3.069-1.574s2.717 0.526 3.731 1.574c1.015 1.048 1.727 2.541 2.14 4.474m-6.756-10.274c-3.314 0-5.568 1.004-6.765 3.015s-1.496 4.43-0.894 7.259c0.59 2.783 1.917 5.193 3.98 7.236 2.064 2.039 4.751 3.06 8.065 3.06 3.313 0 5.566-1.021 6.757-3.06 1.19-2.043 1.491-4.453 0.902-7.236-0.602-2.829-1.931-5.248-3.989-7.259s-4.742-3.015-8.056-3.015" fill="#0071be"/>
</g>
<g transform="translate(1145.9 373.35)">
<path d="m0 0-2.459-11.621c-0.235-1.096-0.283-1.922-0.142-2.477 0.247-0.977 1.043-1.466 2.388-1.466 1.722 0 3.048 0.695 3.98 2.086 0.496 0.756 0.872 1.752 1.132 2.99l2.228 10.488h5.111l-4.085-19.277h-4.898l0.564 2.721c-0.058-0.057-0.212-0.235-0.459-0.53-0.248-0.293-0.525-0.555-0.832-0.777-0.943-0.708-1.813-1.193-2.608-1.451-0.796-0.259-1.689-0.39-2.68-0.39-2.853 0-4.556 1.027-5.111 3.078-0.308 1.132-0.224 2.801 0.247 5.005l2.459 11.621z" fill="#0071be"/>
</g>
<g transform="translate(1174.5 375.62)">
<path d="m0 0h-5.075l-1.627-7.678h5.076c1.285 0 2.352 0.315 3.2 0.94 0.851 0.624 1.416 1.615 1.698 2.969 0.295 1.358 0.145 2.323-0.45 2.901s-1.537 0.868-2.822 0.868m-2.122-12.17h-5.536l-1.981-9.372h-5.412l5.536 26.068h11.355c2.618 0 4.56-0.672 5.827-2.015 1.269-1.345 1.607-3.426 1.018-6.242-0.661-3.079-1.904-5.254-3.732-6.528-1.828-1.273-4.185-1.911-7.075-1.911" fill="#0071be"/>
</g>
<g transform="translate(1188.2 354.07)">
<path d="m0 0h-5.041l5.536 26.068h5.04z" fill="#0071be"/>
</g>
<g transform="translate(1208.4 363.68)">
<path d="m0 0c0.413 1.936 0.334 3.424-0.239 4.467-0.572 1.043-1.594 1.566-3.069 1.566-1.473 0-2.716-0.523-3.731-1.566s-1.728-2.531-2.141-4.467c-0.412-1.933-0.332-3.426 0.24-4.474 0.571-1.048 1.594-1.574 3.068-1.574s2.717 0.526 3.732 1.574c1.014 1.048 1.727 2.541 2.14 4.474m-6.756-10.274c-3.314 0-5.568 1.004-6.765 3.015-1.198 2.011-1.496 4.43-0.894 7.259 0.59 2.783 1.917 5.193 3.98 7.236 2.063 2.039 4.751 3.06 8.065 3.06 3.313 0 5.565-1.021 6.757-3.06 1.19-2.043 1.491-4.453 0.902-7.236-0.602-2.829-1.932-5.248-3.989-7.259-2.058-2.011-4.742-3.015-8.056-3.015" fill="#0071be"/>
</g>
<g transform="translate(1216.5 369.58)">
<path d="m0 0 0.761 3.591h2.688l1.15 5.377h4.988l-1.149-5.377h3.129l-0.76-3.591h-3.13l-2.176-10.186c-0.165-0.792-0.168-1.283-0.01-1.476 0.16-0.196 0.752-0.293 1.779-0.293 0.153 0 0.315 2e-3 0.486 0.01 0.17 6e-3 0.344 0.013 0.521 0.026l-0.812-3.769-2.406-0.088c-2.394-0.081-3.933 0.33-4.618 1.24-0.434 0.577-0.53 1.467-0.282 2.67l2.529 11.866z" fill="#0071be"/>
</g>
<g transform="translate(1072.1 394.28)">
<path d="m0 0 30.155 39.063-31.606 24.4-30.156-39.063zm31.411 39.225-31.25-40.48-33.023 25.493 31.249 40.481z" fill="#000145"/>
</g>
<g transform="translate(1070.3 460.11)">
<path d="m0 0-0.485-0.628-31.249-40.48-0.486-0.628 0.628-0.486 33.025-25.493 0.628-0.485 0.484 0.628 31.25 40.48 0.485 0.628-0.629 0.485-33.023 25.494zm0.143-1.113 33.024-25.494-31.25-40.48-33.023 25.493z" fill="#fff"/>
</g>
<g transform="translate(1071.1 450.66)">
<path d="m0 0-23.69-30.687-2.196 1.694 23.691 30.688z" fill="#0079b7"/>
</g>
<g transform="translate(1068.2 439.15)">
<path d="m0 0-17.041-22.074-2.195 1.694 17.041 22.074z" fill="#0079b7"/>
</g>
<g transform="translate(1066.5 429.09)">
<path d="m0 0-11.519-14.922-2.195 1.694 11.52 14.922z" fill="#0079b7"/>
</g>
<g transform="translate(1067.5 422.7)">
<path d="m0 0-8.821-11.427-2.196 1.695 8.822 11.426z" fill="#0079b7"/>
</g>
<g transform="translate(1078.5 429.09)">
<path d="m0 0-15.994-20.719-2.194 1.695 15.993 20.718z" fill="#0079b7"/>
</g>
<g transform="translate(1088.1 433.83)">
<path d="m0 0-21.892-28.357-2.195 1.694 21.892 28.357z" fill="#0079b7"/>
</g>
<g transform="translate(1089 427.17)">
<path d="m0 0-18.994-24.604-2.195 1.694 18.994 24.604z" fill="#0079b7"/>
</g>
<g transform="translate(1089.7 420.32)">
<path d="m0 0-15.946-20.656-2.196 1.694 15.947 20.657z" fill="#0079b7"/>
</g>
<g transform="translate(1109.2 437.84)">
<path d="m0 0 46.857 15.48-12.524 37.914-46.858-15.48zm47.988 14.911-48.557-16.041-13.087 39.613 48.557 16.041z" fill="#000145"/>
</g>
<g transform="translate(1144.6 493.37)">
<path d="m0 0-0.754-0.248-48.557-16.042-0.753-0.248 0.249-0.754 13.086-39.613 0.249-0.754 0.753 0.249 48.558 16.041 0.754 0.249-0.249 0.754-13.087 39.613zm-0.505-1.002 13.087-39.613-48.558-16.041-13.086 39.613z" fill="#fff"/>
</g>
<g transform="translate(1115.9 448.44)">
<path d="m0 0c0.21-0.637 0.896-0.982 1.533-0.772s0.983 0.897 0.773 1.534c-0.211 0.636-0.898 0.981-1.535 0.771-0.636-0.21-0.981-0.896-0.771-1.533" fill="#0079b7"/>
</g>
<g transform="translate(1134.7 484.29)">
<path d="M 0,0 C 0.21,-0.637 0.897,-0.982 1.533,-0.771 2.17,-0.562 2.516,0.125 2.306,0.762 2.096,1.398 1.408,1.744 0.772,1.534 0.136,1.323 -0.21,0.637 0,0" fill="#0079b7"/>
</g>
<g transform="translate(1127.6 481.3)">
<path d="m0 0c0.21-0.637 0.896-0.982 1.533-0.771 0.637 0.209 0.983 0.896 0.773 1.533-0.211 0.636-0.898 0.982-1.535 0.771-0.636-0.21-0.982-0.896-0.771-1.533" fill="#0079b7"/>
</g>
<g transform="translate(1121.9 457.26)">
<path d="m0 0c0.211-0.637 0.897-0.981 1.534-0.771 0.637 0.209 0.983 0.896 0.772 1.533-0.21 0.636-0.897 0.982-1.534 0.772-0.636-0.211-0.982-0.897-0.772-1.534" fill="#0079b7"/>
</g>
<g transform="translate(1116.4 454.58)">
<path d="m0 0c0.21-0.637 0.897-0.981 1.533-0.771 0.637 0.209 0.983 0.896 0.773 1.533-0.21 0.636-0.898 0.982-1.534 0.772s-0.982-0.897-0.772-1.534" fill="#0079b7"/>
</g>
<g transform="translate(1125.1 463.01)">
<path d="m0 0c0.211-0.637 0.897-0.982 1.534-0.772s0.983 0.897 0.772 1.534c-0.21 0.636-0.897 0.982-1.534 0.771-0.636-0.21-0.982-0.896-0.772-1.533" fill="#0079b7"/>
</g>
<g transform="translate(1125.1 450.66)">
<path d="m0 0c0.21-0.637 0.897-0.981 1.534-0.771 0.637 0.209 0.982 0.896 0.772 1.533-0.21 0.636-0.897 0.982-1.534 0.772-0.636-0.21-0.982-0.897-0.772-1.534" fill="#0079b7"/>
</g>
<g transform="translate(1111.3 458.44)">
<path d="m0 0c0.21-0.637 0.896-0.982 1.533-0.771 0.637 0.209 0.983 0.896 0.773 1.533-0.211 0.636-0.898 0.982-1.535 0.771-0.636-0.21-0.982-0.896-0.771-1.533" fill="#0079b7"/>
</g>
<g transform="translate(1121 445.68)">
<path d="m0 0c0.21-0.637 0.896-0.982 1.533-0.772s0.983 0.897 0.773 1.534c-0.211 0.636-0.898 0.982-1.535 0.771-0.636-0.21-0.982-0.896-0.771-1.533" fill="#0079b7"/>
</g>
<g transform="translate(1141.4 467.03)">
<path d="m0 0c0.399 0.539 0.285 1.3-0.254 1.698-0.539 0.399-1.299 0.285-1.698-0.254s-0.284-1.299 0.255-1.698c0.539-0.398 1.299-0.285 1.697 0.254" fill="#0079b7"/>
</g>
<g transform="translate(1134.3 466.4)">
<path d="m0 0c0.398 0.539 0.285 1.3-0.254 1.698-0.539 0.399-1.3 0.285-1.698-0.254-0.399-0.539-0.285-1.298 0.254-1.698 0.539-0.398 1.3-0.285 1.698 0.254" fill="#0079b7"/>
</g>
<g transform="translate(1141.7 475.64)">
<path d="m0 0c0.398 0.539 0.285 1.299-0.254 1.698s-1.3 0.285-1.698-0.254c-0.399-0.539-0.285-1.299 0.254-1.698s1.3-0.285 1.698 0.254" fill="#0079b7"/>
</g>
<g transform="translate(1129.2 473.3)">
<path d="m0 0c0.398 0.539 0.285 1.3-0.254 1.698-0.539 0.399-1.3 0.285-1.698-0.254-0.4-0.539-0.285-1.299 0.254-1.698 0.539-0.398 1.299-0.285 1.698 0.254" fill="#0079b7"/>
</g>
<g transform="translate(1136.1 474.65)">
<path d="m0 0c0.398 0.539 0.285 1.3-0.254 1.698-0.539 0.399-1.3 0.285-1.698-0.254-0.4-0.539-0.285-1.299 0.254-1.698 0.539-0.398 1.3-0.285 1.698 0.254" fill="#0079b7"/>
</g>
<g transform="translate(1143.5 482.52)">
<path d="m0 0c0.398 0.539 0.285 1.299-0.254 1.698s-1.3 0.285-1.698-0.254c-0.4-0.539-0.285-1.299 0.254-1.698 0.539-0.398 1.299-0.285 1.698 0.254" fill="#0079b7"/>
</g>
<g transform="translate(1111.5 442.95)">
<path d="m0 0c0.211-0.636 0.897-0.981 1.534-0.771 0.637 0.209 0.982 0.896 0.772 1.533-0.21 0.636-0.897 0.982-1.534 0.772-0.636-0.21-0.982-0.897-0.772-1.534" fill="#0079b7"/>
</g>
<g transform="translate(1109.5 451.66)">
<path d="m0 0c0.211-0.637 0.897-0.981 1.534-0.771 0.637 0.209 0.983 0.896 0.772 1.533-0.21 0.636-0.897 0.982-1.534 0.772-0.636-0.211-0.982-0.897-0.772-1.534" fill="#0079b7"/>
</g>
<g transform="translate(1144.5 473.26)">
<path d="m0 0c0.21-0.637 0.896-0.982 1.533-0.771 0.637 0.209 0.983 0.896 0.773 1.533-0.211 0.636-0.898 0.982-1.535 0.771-0.636-0.21-0.982-0.896-0.771-1.533" fill="#0079b7"/>
</g>
<g transform="translate(1166.5 453.32)">
<path d="m0 0 46.857-15.48 12.525 37.913-46.858 15.479zm47.427-16.611-48.558 16.042 13.086 39.612 48.558-16.041z" fill="#000145"/>
</g>
<g transform="translate(1177.9 493.37)">
<path d="m0 0-0.248-0.753-13.087-39.612-0.249-0.754 0.754-0.249 48.558-16.041 0.753-0.249 0.248 0.754 13.087 39.612 0.249 0.754-0.753 0.248-48.558 16.042zm0.505-1.002 48.558-16.041-13.086-39.613-48.558 16.042z" fill="#fff"/>
</g>
<g transform="translate(1174.3 453.88)">
<path d="m0 0-2.487 8.169 0.849 0.259 2.048-6.727 10.265 10.607 2.266-7.448 10.266 10.607 2.267-7.448 10.265 10.606 2.267-7.447 9.74 10.064 0.638-0.618-10.79-11.147-2.266 7.446-10.265-10.606-2.267 7.448-10.265-10.607-2.266 7.447z" fill="#0079b7"/>
</g>
<g transform="translate(1220.3 433.35)">
<path d="m0 0 30.156-39.063 31.607 24.399-30.156 39.063zm29.994-40.319-31.249 40.48 33.024 25.493 31.25-40.479z" fill="#000145"/>
</g>
<g transform="translate(1252.2 460.11)">
<path d="m0 0-0.629-0.484-33.023-25.495-0.628-0.484 0.484-0.629 31.25-40.479 0.485-0.628 0.628 0.484 33.024 25.494 0.628 0.485-0.485 0.628-31.25 40.48zm-0.144-1.113 31.249-40.48-33.022-25.493-31.25 40.48z" fill="#fff"/>
</g>
<g transform="translate(1228 429.97)">
<path d="m0 0 7.732-10.017 4.727 3.65-7.732 10.016zm7.572-11.262-8.818 11.423 6.133 4.735 8.817-11.423z" fill="#0079b7"/>
</g>
<g transform="translate(1232.8 422.93)">
<path d="m0 0-0.543 0.703 5.43 4.193 0.543-0.704z" fill="#0079b7"/>
</g>
<g transform="translate(1239.9 413.79)">
<path d="m0 0-0.543 0.703 5.43 4.192 0.543-0.703z" fill="#0079b7"/>
</g>
<g transform="translate(1225.2 432.78)">
<path d="m0 0-0.543 0.702 5.43 4.193 0.543-0.704z" fill="#0079b7"/>
</g>
<g transform="translate(1242.1 415.85)">
<path d="m0 0-4.191 5.43 0.703 0.543 4.191-5.43z" fill="#0079b7"/>
</g>
<g transform="translate(1229.5 432.12)">
<path d="m0 0-2.096 2.715 0.703 0.543 2.096-2.715z" fill="#0079b7"/>
</g>
<g transform="translate(1263.1 426.88)">
<path d="m0 0 6.573-8.515 4.727 3.649-6.573 8.514zm6.413-9.761-7.658 9.921 6.132 4.734 7.658-9.92z" fill="#0079b7"/>
</g>
<g transform="translate(1265.1 423.6)">
<path d="m0 0-0.543 0.702 5.429 4.192 0.543-0.704z" fill="#0079b7"/>
</g>
<g transform="translate(1272.1 414.47)">
<path d="m0 0-0.542 0.703 5.429 4.192 0.543-0.704z" fill="#0079b7"/>
</g>
<g transform="translate(1261.2 428.67)">
<path d="m0 0-0.543 0.703 5.43 4.192 0.543-0.704z" fill="#0079b7"/>
</g>
<g transform="translate(1274.3 416.52)">
<path d="m0 0-2.445 3.168 0.703 0.543 2.445-3.168z" fill="#0079b7"/>
</g>
<g transform="translate(1264.7 429.03)">
<path d="m0 0-1.302 1.685 0.703 0.543 1.301-1.686z" fill="#0079b7"/>
</g>
<g transform="translate(1240.8 434.62)">
<path d="m0 0 13.419-17.383 4.727 3.649-13.419 17.382zm13.259-18.629-14.504 18.789 6.133 4.735 14.504-18.79z" fill="#0079b7"/>
</g>
<g transform="translate(1250.8 420.93)">
<path d="m0 0-0.543 0.703 5.43 4.192 0.543-0.703z" fill="#0079b7"/>
</g>
<g transform="translate(1261.9 406.54)">
<path d="m0 0-0.543 0.703 5.43 4.192 0.543-0.703z" fill="#0079b7"/>
</g>
<g transform="translate(1238 437.43)">
<path d="m0 0-0.542 0.703 5.43 4.192 0.543-0.704z" fill="#0079b7"/>
</g>
<g transform="translate(1264.1 408.6)">
<path d="m0 0-7.612 9.861 0.702 0.543 7.612-9.861z" fill="#0079b7"/>
</g>
<g transform="translate(1242.3 436.77)">
<path d="m0 0-2.096 2.715 0.703 0.542 2.096-2.714z" fill="#0079b7"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

151
test/fixtures/IRIStsv.tsv vendored Normal file
View File

@ -0,0 +1,151 @@
sepal_length sepal_width petal_length petal_width species
5.1 3.5 1.4 0.2 Iris-setosa
4.9 3 1.4 0.2 Iris-setosa
4.7 3.2 1.3 0.2 Iris-setosa
4.6 3.1 1.5 0.2 Iris-setosa
5 3.6 1.4 0.2 Iris-setosa
5.4 3.9 1.7 0.4 Iris-setosa
4.6 3.4 1.4 0.3 Iris-setosa
5 3.4 1.5 0.2 Iris-setosa
4.4 2.9 1.4 0.2 Iris-setosa
4.9 3.1 1.5 0.1 Iris-setosa
5.4 3.7 1.5 0.2 Iris-setosa
4.8 3.4 1.6 0.2 Iris-setosa
4.8 3 1.4 0.1 Iris-setosa
4.3 3 1.1 0.1 Iris-setosa
5.8 4 1.2 0.2 Iris-setosa
5.7 4.4 1.5 0.4 Iris-setosa
5.4 3.9 1.3 0.4 Iris-setosa
5.1 3.5 1.4 0.3 Iris-setosa
5.7 3.8 1.7 0.3 Iris-setosa
5.1 3.8 1.5 0.3 Iris-setosa
5.4 3.4 1.7 0.2 Iris-setosa
5.1 3.7 1.5 0.4 Iris-setosa
4.6 3.6 1 0.2 Iris-setosa
5.1 3.3 1.7 0.5 Iris-setosa
4.8 3.4 1.9 0.2 Iris-setosa
5 3 1.6 0.2 Iris-setosa
5 3.4 1.6 0.4 Iris-setosa
5.2 3.5 1.5 0.2 Iris-setosa
5.2 3.4 1.4 0.2 Iris-setosa
4.7 3.2 1.6 0.2 Iris-setosa
4.8 3.1 1.6 0.2 Iris-setosa
5.4 3.4 1.5 0.4 Iris-setosa
5.2 4.1 1.5 0.1 Iris-setosa
5.5 4.2 1.4 0.2 Iris-setosa
4.9 3.1 1.5 0.1 Iris-setosa
5 3.2 1.2 0.2 Iris-setosa
5.5 3.5 1.3 0.2 Iris-setosa
4.9 3.1 1.5 0.1 Iris-setosa
4.4 3 1.3 0.2 Iris-setosa
5.1 3.4 1.5 0.2 Iris-setosa
5 3.5 1.3 0.3 Iris-setosa
4.5 2.3 1.3 0.3 Iris-setosa
4.4 3.2 1.3 0.2 Iris-setosa
5 3.5 1.6 0.6 Iris-setosa
5.1 3.8 1.9 0.4 Iris-setosa
4.8 3 1.4 0.3 Iris-setosa
5.1 3.8 1.6 0.2 Iris-setosa
4.6 3.2 1.4 0.2 Iris-setosa
5.3 3.7 1.5 0.2 Iris-setosa
5 3.3 1.4 0.2 Iris-setosa
7 3.2 4.7 1.4 Iris-versicolor
6.4 3.2 4.5 1.5 Iris-versicolor
6.9 3.1 4.9 1.5 Iris-versicolor
5.5 2.3 4 1.3 Iris-versicolor
6.5 2.8 4.6 1.5 Iris-versicolor
5.7 2.8 4.5 1.3 Iris-versicolor
6.3 3.3 4.7 1.6 Iris-versicolor
4.9 2.4 3.3 1 Iris-versicolor
6.6 2.9 4.6 1.3 Iris-versicolor
5.2 2.7 3.9 1.4 Iris-versicolor
5 2 3.5 1 Iris-versicolor
5.9 3 4.2 1.5 Iris-versicolor
6 2.2 4 1 Iris-versicolor
6.1 2.9 4.7 1.4 Iris-versicolor
5.6 2.9 3.6 1.3 Iris-versicolor
6.7 3.1 4.4 1.4 Iris-versicolor
5.6 3 4.5 1.5 Iris-versicolor
5.8 2.7 4.1 1 Iris-versicolor
6.2 2.2 4.5 1.5 Iris-versicolor
5.6 2.5 3.9 1.1 Iris-versicolor
5.9 3.2 4.8 1.8 Iris-versicolor
6.1 2.8 4 1.3 Iris-versicolor
6.3 2.5 4.9 1.5 Iris-versicolor
6.1 2.8 4.7 1.2 Iris-versicolor
6.4 2.9 4.3 1.3 Iris-versicolor
6.6 3 4.4 1.4 Iris-versicolor
6.8 2.8 4.8 1.4 Iris-versicolor
6.7 3 5 1.7 Iris-versicolor
6 2.9 4.5 1.5 Iris-versicolor
5.7 2.6 3.5 1 Iris-versicolor
5.5 2.4 3.8 1.1 Iris-versicolor
5.5 2.4 3.7 1 Iris-versicolor
5.8 2.7 3.9 1.2 Iris-versicolor
6 2.7 5.1 1.6 Iris-versicolor
5.4 3 4.5 1.5 Iris-versicolor
6 3.4 4.5 1.6 Iris-versicolor
6.7 3.1 4.7 1.5 Iris-versicolor
6.3 2.3 4.4 1.3 Iris-versicolor
5.6 3 4.1 1.3 Iris-versicolor
5.5 2.5 4 1.3 Iris-versicolor
5.5 2.6 4.4 1.2 Iris-versicolor
6.1 3 4.6 1.4 Iris-versicolor
5.8 2.6 4 1.2 Iris-versicolor
5 2.3 3.3 1 Iris-versicolor
5.6 2.7 4.2 1.3 Iris-versicolor
5.7 3 4.2 1.2 Iris-versicolor
5.7 2.9 4.2 1.3 Iris-versicolor
6.2 2.9 4.3 1.3 Iris-versicolor
5.1 2.5 3 1.1 Iris-versicolor
5.7 2.8 4.1 1.3 Iris-versicolor
6.3 3.3 6 2.5 Iris-virginica
5.8 2.7 5.1 1.9 Iris-virginica
7.1 3 5.9 2.1 Iris-virginica
6.3 2.9 5.6 1.8 Iris-virginica
6.5 3 5.8 2.2 Iris-virginica
7.6 3 6.6 2.1 Iris-virginica
4.9 2.5 4.5 1.7 Iris-virginica
7.3 2.9 6.3 1.8 Iris-virginica
6.7 2.5 5.8 1.8 Iris-virginica
7.2 3.6 6.1 2.5 Iris-virginica
6.5 3.2 5.1 2 Iris-virginica
6.4 2.7 5.3 1.9 Iris-virginica
6.8 3 5.5 2.1 Iris-virginica
5.7 2.5 5 2 Iris-virginica
5.8 2.8 5.1 2.4 Iris-virginica
6.4 3.2 5.3 2.3 Iris-virginica
6.5 3 5.5 1.8 Iris-virginica
7.7 3.8 6.7 2.2 Iris-virginica
7.7 2.6 6.9 2.3 Iris-virginica
6 2.2 5 1.5 Iris-virginica
6.9 3.2 5.7 2.3 Iris-virginica
5.6 2.8 4.9 2 Iris-virginica
7.7 2.8 6.7 2 Iris-virginica
6.3 2.7 4.9 1.8 Iris-virginica
6.7 3.3 5.7 2.1 Iris-virginica
7.2 3.2 6 1.8 Iris-virginica
6.2 2.8 4.8 1.8 Iris-virginica
6.1 3 4.9 1.8 Iris-virginica
6.4 2.8 5.6 2.1 Iris-virginica
7.2 3 5.8 1.6 Iris-virginica
7.4 2.8 6.1 1.9 Iris-virginica
7.9 3.8 6.4 2 Iris-virginica
6.4 2.8 5.6 2.2 Iris-virginica
6.3 2.8 5.1 1.5 Iris-virginica
6.1 2.6 5.6 1.4 Iris-virginica
7.7 3 6.1 2.3 Iris-virginica
6.3 3.4 5.6 2.4 Iris-virginica
6.4 3.1 5.5 1.8 Iris-virginica
6 3 4.8 1.8 Iris-virginica
6.9 3.1 5.4 2.1 Iris-virginica
6.7 3.1 5.6 2.4 Iris-virginica
6.9 3.1 5.1 2.3 Iris-virginica
5.8 2.7 5.1 1.9 Iris-virginica
6.8 3.2 5.9 2.3 Iris-virginica
6.7 3.3 5.7 2.5 Iris-virginica
6.7 3 5.2 2.3 Iris-virginica
6.3 2.5 5 1.9 Iris-virginica
6.5 3 5.2 2 Iris-virginica
6.2 3.4 5.4 2.3 Iris-virginica
5.9 3 5.1 1.8 Iris-virginica
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 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 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 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 1.4 0.1 Iris-setosa
15 4.3 3 1.1 0.1 Iris-setosa
16 5.8 4 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.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 3 1.6 0.2 Iris-setosa
28 5 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 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 1.3 0.2 Iris-setosa
41 5.1 3.4 1.5 0.2 Iris-setosa
42 5 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 3.5 1.6 0.6 Iris-setosa
46 5.1 3.8 1.9 0.4 Iris-setosa
47 4.8 3 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 3.3 1.4 0.2 Iris-setosa
52 7 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 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 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 2 3.5 1 Iris-versicolor
63 5.9 3 4.2 1.5 Iris-versicolor
64 6 2.2 4 1 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 4.5 1.5 Iris-versicolor
69 5.8 2.7 4.1 1 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 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 4.4 1.4 Iris-versicolor
78 6.8 2.8 4.8 1.4 Iris-versicolor
79 6.7 3 5 1.7 Iris-versicolor
80 6 2.9 4.5 1.5 Iris-versicolor
81 5.7 2.6 3.5 1 Iris-versicolor
82 5.5 2.4 3.8 1.1 Iris-versicolor
83 5.5 2.4 3.7 1 Iris-versicolor
84 5.8 2.7 3.9 1.2 Iris-versicolor
85 6 2.7 5.1 1.6 Iris-versicolor
86 5.4 3 4.5 1.5 Iris-versicolor
87 6 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 4.1 1.3 Iris-versicolor
91 5.5 2.5 4 1.3 Iris-versicolor
92 5.5 2.6 4.4 1.2 Iris-versicolor
93 6.1 3 4.6 1.4 Iris-versicolor
94 5.8 2.6 4 1.2 Iris-versicolor
95 5 2.3 3.3 1 Iris-versicolor
96 5.6 2.7 4.2 1.3 Iris-versicolor
97 5.7 3 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 1.1 Iris-versicolor
101 5.7 2.8 4.1 1.3 Iris-versicolor
102 6.3 3.3 6 2.5 Iris-virginica
103 5.8 2.7 5.1 1.9 Iris-virginica
104 7.1 3 5.9 2.1 Iris-virginica
105 6.3 2.9 5.6 1.8 Iris-virginica
106 6.5 3 5.8 2.2 Iris-virginica
107 7.6 3 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 Iris-virginica
113 6.4 2.7 5.3 1.9 Iris-virginica
114 6.8 3 5.5 2.1 Iris-virginica
115 5.7 2.5 5 2 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 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 2.2 5 1.5 Iris-virginica
122 6.9 3.2 5.7 2.3 Iris-virginica
123 5.6 2.8 4.9 2 Iris-virginica
124 7.7 2.8 6.7 2 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 1.8 Iris-virginica
128 6.2 2.8 4.8 1.8 Iris-virginica
129 6.1 3 4.9 1.8 Iris-virginica
130 6.4 2.8 5.6 2.1 Iris-virginica
131 7.2 3 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 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 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 3 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 5.2 2.3 Iris-virginica
148 6.3 2.5 5 1.9 Iris-virginica
149 6.5 3 5.2 2 Iris-virginica
150 6.2 3.4 5.4 2.3 Iris-virginica
151 5.9 3 5.1 1.8 Iris-virginica

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

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

12
test/fixtures/simple-count.txt vendored Normal file
View File

@ -0,0 +1,12 @@
┌ ┐
-10 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
-20 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
-30 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
-40 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
-50 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
10 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
20 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
30 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
40 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
50 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1.0
└ ┘

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

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

View File

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

View File

@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │ |│
│ ., /│
│ .\ /│
│ .\ |\ .`│
│ , /\ ,`", . │
│ /|. .` . / \ | │
│ .\. .` \ / l / \ | │
│-----^r----^---r--------r--------r---|--│
│.` \. | \ / | | \ | │
│` \./ . .` |. | \ | │
│ \` |./ . . ", ,` │
│ \` \ | \ / │
│ " |` \ | │
│ / ",` │
-50 │ Y │
└────────────────────────────────────────┘
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,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,18 @@
┌─────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⣧⠀⠀⢸⢣⠀⠀⢸│
│⠀⠀⠀⠀⠀⢠⠀⠀⠀⣿⠀⠀⢸⢸⠀⠀⡇│
│⠀⠀⠀⠀⠀⣾⠀⠀⢰⢹⠀⠀⢸⢸⠀⠀⡇│
│⠀⡸⡄⠀⢀⠇⡇⠀⢸⠈⡆⠀⡎⢸⠀⠀⡇│
│⢤⠧⢧⠤⢼⠤⡧⠤⡼⠤⡧⠤⡧⠬⡦⠤⡧│
│⡎⠀⠸⡀⡎⠀⢸⠀⡇⠀⡇⠀⡇⠀⡇⢸⠀│
│⠁⠀⠀⡇⡇⠀⢸⠀⡇⠀⢸⢠⠃⠀⡇⢸⠀│
│⠀⠀⠀⠸⠀⠀⠀⣿⠀⠀⢸⢸⠀⠀⢇⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠸⣸⠀⠀⢸⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⡟⠀⠀⢸⡇⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠇⠀⠀⢸⡇⠀│
-50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡇⠀│
└─────────────────┘
1 10

View File

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

View File

@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢳⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇⠈⡆⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⠀⠸⡀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⡜⠀⠀⠀⠀⢣⠀⠀⠀⠀│
│⠉⠉⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⠉⠉⠉⡩⠋⠉⠉⠉⠉⠉⠹⡉⠉⠉⠉⠉⠉⡹⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀⠀⢰⠁⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⡄⠀⢠⠃⠀⠀⠀⠀⠀⠀⠀⠀⢣⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣄⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆⠀│
-25 │⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀│
└────────────────────────────────────────┘
-1 5

View File

@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣄⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠈⡆⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠊⠣⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠀⠘⡄⠀⠀⠀⠀│
│⠤⠤⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⠤⠤⠤⢤⠴⠥⠤⠤⠤⠵⢤⠤⠤⠤⠤⠤⠤⢤⠮⠤⠤⠤⠤⠼⡤⠤⠤⠤│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀⢠⠃⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⢠⠃⠀⠀⠀⠀⠀⠀⠀⠀⢱⠀⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠲⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⠀│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈│
│⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
-50 │⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
└────────────────────────────────────────┘
-1 5

View File

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

View File

@ -0,0 +1,18 @@
┌────────────────────────────────────────┐
50 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡇⠀⠀⠀⠀⠀⠀⠀⡜│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢇⠀⠀⠀⠀⠀⠀⠀⡇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀⡎⢸⠀⠀⠀⠀⠀⠀⢀⠇│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢸⠀⠀⠀⠀⠀⠀⠀⡇⠸⡀⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢧⠀⠀⠀⠀⠀⠀⠀⡇⠘⡄⠀⠀⠀⠀⠀⢸⠀⠀⡇⠀⠀⠀⠀⠀⢸⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠸⡀⠀⠀⠀⠀⠀⢠⠃⠀⡇⠀⠀⠀⠀⠀⢸⠀⠀⢇⠀⠀⠀⠀⠀⡇⠀│
│⠀⠀⠀⢠⠳⡀⠀⠀⠀⠀⠀⢠⠃⠀⢇⠀⠀⠀⠀⠀⡸⠀⠀⢱⠀⠀⠀⠀⠀⡇⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀│
│⠀⠀⡠⠃⠀⢣⠀⠀⠀⠀⠀⡜⠀⠀⢸⠀⠀⠀⠀⠀⡇⠀⠀⠸⡀⠀⠀⠀⢀⠇⠀⠀⠸⡀⠀⠀⠀⢰⠁⠀│
│⠉⡹⠉⠉⠉⠉⡏⠉⠉⠉⢹⠉⠉⠉⠉⡏⠉⠉⠉⢹⠉⠉⠉⠉⡏⠉⠉⠉⢹⠉⠉⠉⠉⡏⠉⠉⠉⢹⠉⠉│
│⡰⠁⠀⠀⠀⠀⠘⡄⠀⠀⡎⠀⠀⠀⠀⢸⠀⠀⠀⡜⠀⠀⠀⠀⢱⠀⠀⠀⡜⠀⠀⠀⠀⢇⠀⠀⠀⡜⠀⠀│
│⠁⠀⠀⠀⠀⠀⠀⢱⠀⢰⠁⠀⠀⠀⠀⠈⡆⠀⢀⠇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀⠀⠀⢸⠀⠀⠀⡇⠀⠀│
│⠀⠀⠀⠀⠀⠀⠀⠀⢣⡇⠀⠀⠀⠀⠀⠀⢱⠀⢸⠀⠀⠀⠀⠀⠀⡇⠀⢰⠁⠀⠀⠀⠀⠸⡀⠀⢀⠇⠀⠀│
-25 │⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠘⡄⡎⠀⠀⠀⠀⠀⠀⢣⠀⣸⠀⠀⠀⠀⠀⠀⡇⠀⢸⠀⠀⠀│
└────────────────────────────────────────┘
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

20
test/unicode_plot_test.rb Normal file
View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
require_relative 'test_helper'
require 'unicode_plot'
# Check the UnicodePlot constants that YouPlot depends on.
# Prepare for UnicodePlot version upgrades.
class UnicodePlotTest < Test::Unit::TestCase
test 'VERSION' do
assert UnicodePlot::VERSION
end
test 'BORDER_MAP' do
assert_instance_of Hash, UnicodePlot::BORDER_MAP
end
test 'PREDEFINED_TRANSFORM_FUNCTIONS' do
assert_instance_of Hash, UnicodePlot::ValueTransformer::PREDEFINED_TRANSFORM_FUNCTIONS
end
end

View File

@ -2,10 +2,16 @@
require_relative '../../test_helper'
class YouPlotCommandTest < Test::Unit::TestCase
class ProcessingTest < Test::Unit::TestCase
test :count_values do
@m = YouPlot::Backends::Processing
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

@ -1,6 +0,0 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class YouPlotPlotTest < Test::Unit::TestCase
end

View File

@ -1,102 +0,0 @@
# frozen_string_literal: true
require 'tempfile'
require_relative '../test_helper'
class YouPlotCommandTest < Test::Unit::TestCase
class << self
def startup
@stdin = $stdin.dup
@stderr = $stderr.dup
end
def shutdown
$stdin = @stdin
$stderr = @stderr
end
end
def setup
$stdin = File.open(File.expand_path('../fixtures/iris.csv', __dir__), 'r')
@tmp_file = Tempfile.new
$stderr = @tmp_file
end
def teardown
@tmp_file.close
end
def fixture(fname)
File.read(File.expand_path("../fixtures/#{fname}", __dir__))
end
test :bar do
YouPlot::Command.new(['bar', '-H', '-d,', '-t', 'IRIS-BARPLOT']).run
assert_equal fixture('iris-barplot.txt'), @tmp_file.read
end
test :barplot do
YouPlot::Command.new(['barplot', '-H', '-d,', '-t', 'IRIS-BARPLOT']).run
assert_equal fixture('iris-barplot.txt'), @tmp_file.read
end
test :hist do
YouPlot::Command.new(['hist', '-H', '-d,', '-t', 'IRIS-HISTOGRAM']).run
assert_equal fixture('iris-histogram.txt'), @tmp_file.read
end
test :histogram do
YouPlot::Command.new(['histogram', '-H', '-d,', '-t', 'IRIS-HISTOGRAM']).run
assert_equal fixture('iris-histogram.txt'), @tmp_file.read
end
test :line do
YouPlot::Command.new(['line', '-H', '-d,', '-t', 'IRIS-LINEPLOT']).run
assert_equal fixture('iris-lineplot.txt'), @tmp_file.read
end
test :lineplot do
YouPlot::Command.new(['lineplot', '-H', '-d,', '-t', 'IRIS-LINEPLOT']).run
assert_equal fixture('iris-lineplot.txt'), @tmp_file.read
end
test :lines do
YouPlot::Command.new(['lines', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run
assert_equal fixture('iris-lineplots.txt'), @tmp_file.read
end
test :lineplots do
YouPlot::Command.new(['lineplots', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run
assert_equal fixture('iris-lineplots.txt'), @tmp_file.read
end
test :s do
YouPlot::Command.new(['s', '-H', '-d,', '-t', 'IRIS-SCATTER']).run
assert_equal fixture('iris-scatter.txt'), @tmp_file.read
end
test :scatter do
YouPlot::Command.new(['scatter', '-H', '-d,', '-t', 'IRIS-SCATTER']).run
assert_equal fixture('iris-scatter.txt'), @tmp_file.read
end
test :d do
YouPlot::Command.new(['d', '-H', '-d,', '-t', 'IRIS-DENSITY']).run
assert_equal fixture('iris-density.txt'), @tmp_file.read
end
test :density do
YouPlot::Command.new(['density', '-H', '-d,', '-t', 'IRIS-DENSITY']).run
assert_equal fixture('iris-density.txt'), @tmp_file.read
end
test :box do
YouPlot::Command.new(['box', '-H', '-d,', '-t', 'IRIS-BOXPLOT']).run
assert_equal fixture('iris-boxplot.txt'), @tmp_file.read
end
test :boxplot do
YouPlot::Command.new(['boxplot', '-H', '-d,', '-t', 'IRIS-BOXPLOT']).run
assert_equal fixture('iris-boxplot.txt'), @tmp_file.read
end
end

View File

@ -2,9 +2,9 @@
require_relative '../test_helper'
class YouPlotDSVReaderTest < Test::Unit::TestCase
class YouPlotDSVTest < Test::Unit::TestCase
def setup
@m = YouPlot::DSVReader
@m = YouPlot::DSV
end
test :transpose2 do
@ -59,6 +59,8 @@ class YouPlotDSVReaderTest < Test::Unit::TestCase
assert_equal(nil, @m.get_headers([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], false, false))
assert_equal([1, 2, 3], @m.get_headers([[1, 2, 3]], true, false))
end
test :get_series do
@ -123,5 +125,7 @@ class YouPlotDSVReaderTest < 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))
end
end

178
test/youplot/iris_test.rb Normal file
View File

@ -0,0 +1,178 @@
# frozen_string_literal: true
require 'tempfile'
require_relative '../test_helper'
class YouPlotIRISTest < 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/iris.csv', __dir__), 'r')
@stderr_file = Tempfile.new
@stdout_file = Tempfile.new
$stderr = @stderr_file
$stdout = @stdout_file
end
def teardown
@stderr_file.close
@stdout_file.close
end
def fixture(fname)
File.read(File.expand_path("../fixtures/#{fname}", __dir__))
end
test :barplot do
YouPlot::Command.new(['barplot', '-H', '-d,', '-t', 'IRIS-BARPLOT']).run
assert_equal fixture('iris-barplot.txt'), @stderr_file.read
end
# barplot doesn't make sense, but just to make sure it works.
test :bar do
YouPlot::Command.new(['bar', '-H', '-d,', '-t', 'IRIS-BARPLOT']).run
assert_equal fixture('iris-barplot.txt'), @stderr_file.read
end
test :histogram do
YouPlot::Command.new(['histogram', '-H', '-d,', '-t', 'IRIS-HISTOGRAM']).run
assert_equal fixture('iris-histogram.txt'), @stderr_file.read
end
test :hist do
YouPlot::Command.new(['hist', '-H', '-d,', '-t', 'IRIS-HISTOGRAM']).run
assert_equal fixture('iris-histogram.txt'), @stderr_file.read
end
# Yeah, lineplot/lineplots don't make sense too.
test :lineplot do
YouPlot::Command.new(['lineplot', '-H', '-d,', '-t', 'IRIS-LINEPLOT']).run
assert_equal fixture('iris-lineplot.txt'), @stderr_file.read
end
test :line do
YouPlot::Command.new(['line', '-H', '-d,', '-t', 'IRIS-LINEPLOT']).run
assert_equal fixture('iris-lineplot.txt'), @stderr_file.read
end
# l is an undocumented alias of lineplot.
test :l do
YouPlot::Command.new(['l', '-H', '-d,', '-t', 'IRIS-LINEPLOT']).run
assert_equal fixture('iris-lineplot.txt'), @stderr_file.read
end
test :lineplots do
YouPlot::Command.new(['lineplots', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run
assert_equal fixture('iris-lineplots.txt'), @stderr_file.read
end
test :lines do
YouPlot::Command.new(['lines', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run
assert_equal fixture('iris-lineplots.txt'), @stderr_file.read
end
# ls is an undocumented alias of lineplots.
test :ls do
YouPlot::Command.new(['lines', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run
assert_equal fixture('iris-lineplots.txt'), @stderr_file.read
end
test :scatter do
YouPlot::Command.new(['scatter', '-H', '-d,', '-t', 'IRIS-SCATTER']).run
assert_equal fixture('iris-scatter.txt'), @stderr_file.read
end
test :s do
YouPlot::Command.new(['s', '-H', '-d,', '-t', 'IRIS-SCATTER']).run
assert_equal fixture('iris-scatter.txt'), @stderr_file.read
end
test :density do
YouPlot::Command.new(['density', '-H', '-d,', '-t', 'IRIS-DENSITY']).run
assert_equal fixture('iris-density.txt'), @stderr_file.read
end
test :d do
YouPlot::Command.new(['d', '-H', '-d,', '-t', 'IRIS-DENSITY']).run
assert_equal fixture('iris-density.txt'), @stderr_file.read
end
test :boxplot do
YouPlot::Command.new(['boxplot', '-H', '-d,', '-t', 'IRIS-BOXPLOT']).run
assert_equal fixture('iris-boxplot.txt'), @stderr_file.read
end
test :box do
YouPlot::Command.new(['box', '-H', '-d,', '-t', 'IRIS-BOXPLOT']).run
assert_equal fixture('iris-boxplot.txt'), @stderr_file.read
end
# Yeah, lineplot/lineplots don't make sense too.
# Just checking the behavior.
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
# Output options.
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 fixture('iris.csv'), @stdout_file.read
end
%i[colors color colours colour].each do |cmd_name|
test cmd_name do
YouPlot::Command.new([cmd_name.to_s]).run
assert_equal fixture('colors.txt'), @stderr_file.read
assert_equal '', @stdout_file.read
end
end
test :colors_output_stdout do
YouPlot::Command.new(['colors', '-o']).run
assert_equal '', @stderr_file.read
assert_equal fixture('colors.txt'), @stdout_file.read
end
test :unrecognized_command do
assert_raise(YouPlot::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

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

@ -0,0 +1,272 @@
# 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
@stdout_file.close
end
def fixture(fname)
File.read(File.expand_path("../fixtures/#{fname}", __dir__))
end
# Single command
# The goal is to verify that the command works without any options.
test :barplot do
assert_raise(ArgumentError) do
YouPlot::Command.new(['barplot']).run
end
end
test :bar do
assert_raise(ArgumentError) do
YouPlot::Command.new(['bar']).run
end
end
test :histogram do
YouPlot::Command.new(['histogram']).run
assert_equal fixture('simple-histogram.txt'), @stderr_file.read
end
test :hist do
YouPlot::Command.new(['hist']).run
assert_equal fixture('simple-histogram.txt'), @stderr_file.read
end
test :lineplot do
YouPlot::Command.new(['lineplot']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :line do
YouPlot::Command.new(['line']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :lineplots do
assert_raise(YouPlot::Backends::UnicodePlot::Error) do
YouPlot::Command.new(['lineplots']).run
end
end
test :lines do
assert_raise(YouPlot::Backends::UnicodePlot::Error) do
YouPlot::Command.new(['lines']).run
end
end
test :scatter do
assert_raise(YouPlot::Backends::UnicodePlot::Error) do
YouPlot::Command.new(['scatter']).run
end
end
test :s do
assert_raise(YouPlot::Backends::UnicodePlot::Error) do
YouPlot::Command.new(['s']).run
end
end
test :density do
assert_raise(YouPlot::Backends::UnicodePlot::Error) do
YouPlot::Command.new(['density']).run
end
end
test :d do
assert_raise(YouPlot::Backends::UnicodePlot::Error) do
YouPlot::Command.new(['d']).run
end
end
test :boxplot do
YouPlot::Command.new(['boxplot']).run
assert_equal fixture('simple-boxplot.txt'), @stderr_file.read
end
test :box do
YouPlot::Command.new(['box']).run
assert_equal fixture('simple-boxplot.txt'), @stderr_file.read
end
test :count do
YouPlot::Command.new(['c']).run
assert_equal fixture('simple-count.txt'), @stderr_file.read
end
test :c do
YouPlot::Command.new(['count']).run
assert_equal fixture('simple-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_ylabel do
YouPlot::Command.new(['line', '--ylabel', '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', '-h', '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
test :line_border_corners do
YouPlot::Command.new(['line', '--border', 'corners']).run
assert_equal fixture('simple-lineplot-border-corners.txt'), @stderr_file.read
end
test :line_b_corners do
YouPlot::Command.new(['line', '-b', 'corners']).run
assert_equal fixture('simple-lineplot-border-corners.txt'), @stderr_file.read
end
test :line_border_barplot do
YouPlot::Command.new(['line', '--border', 'barplot']).run
assert_equal fixture('simple-lineplot-border-barplot.txt'), @stderr_file.read
end
test :line_b_barplot do
YouPlot::Command.new(['line', '-b', 'barplot']).run
assert_equal fixture('simple-lineplot-border-barplot.txt'), @stderr_file.read
end
test :line_canvas_ascii do
YouPlot::Command.new(['line', '--canvas', 'ascii']).run
assert_equal fixture('simple-lineplot-canvas-ascii.txt'), @stderr_file.read
end
test :line_canvas_braille do
YouPlot::Command.new(['line', '--canvas', 'braille']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :line_canvas_density do
YouPlot::Command.new(['line', '--canvas', 'density']).run
assert_equal fixture('simple-lineplot-canvas-density.txt'), @stderr_file.read
end
test :line_canvas_dot do
YouPlot::Command.new(['line', '--canvas', 'dot']).run
assert_equal fixture('simple-lineplot-canvas-dot.txt'), @stderr_file.read
end
# test :line_canvas_block do
# YouPlot::Command.new(['line', '--canvas', 'block']).run
# assert_equal fixture('simple-lineplot-canvas-dot.txt'), @stderr_file.read
# end
test :hist_symbol_atmark do
YouPlot::Command.new(['hist', '--symbol', '@']).run
assert_equal fixture('simple-histogram-symbol-@.txt'), @stderr_file.read
end
test :line_xlim do
YouPlot::Command.new(['line', '--xlim', '-1,5']).run
assert_equal fixture('simple-lineplot-xlim--1-5.txt'), @stderr_file.read
end
test :line_ylim do
YouPlot::Command.new(['line', '--ylim', '-25,50']).run
assert_equal fixture('simple-lineplot-ylim--25-50.txt'), @stderr_file.read
end
test :line_xlim_and_ylim do
YouPlot::Command.new(['line', '--xlim', '-1,5', '--ylim', '-25,50']).run
assert_equal fixture('simple-lineplot-xlim--1-5-ylim--25-50.txt'), @stderr_file.read
end
test :line_grid do
YouPlot::Command.new(['line', '--grid']).run
assert_equal fixture('simple-lineplot.txt'), @stderr_file.read
end
test :line_no_grid do
YouPlot::Command.new(['line', '--no-grid']).run
assert_equal fixture('simple-lineplot-no-grid.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

@ -8,24 +8,17 @@ Gem::Specification.new do |spec|
spec.authors = ['kojix2']
spec.email = ['2xijok@gmail.com']
spec.summary = 'Create Ascii charts on your terminal.'
spec.description = <<~MSG
Create ASCII charts on the terminal with data from standard streams in the
pipeline.
MSG
spec.homepage = 'https://github.com/kojix2/youplot'
spec.summary = 'A command line tool for Unicode Plotting'
spec.description = 'A command line tool for Unicode Plotting'
spec.homepage = 'https://github.com/red-data-tools/YouPlot'
spec.license = 'MIT'
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
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'
spec.add_development_dependency 'bundler'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rubocop'
spec.add_development_dependency 'simplecov'
spec.add_development_dependency 'test-unit'
spec.add_dependency 'csv'
spec.add_dependency 'unicode_plot', '>= 0.0.5'
end