Compare commits

..

No commits in common. "main" and "v0.4.3" have entirely different histories.
main ... v0.4.3

10 changed files with 37 additions and 252 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: kojix2
ko_fi: kojix2

View File

@ -1,15 +1,15 @@
name: test name: test
on: [push, pull_request, workflow_dispatch] on: [push, pull_request]
jobs: jobs:
build: build:
name: ${{ matrix.os }} Ruby ${{ matrix.ruby }} name: ${{ matrix.os }} Ruby ${{ matrix.ruby }}
runs-on: ${{ matrix.os }}-latest runs-on: ${{ matrix.os }}-latest
strategy: strategy:
matrix: matrix:
os: ["ubuntu", "macos"] os: ['ubuntu', 'macos']
ruby: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "head"] ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1 - uses: ruby/setup-ruby@v1
with: with:
ruby-version: ${{ matrix.ruby }} ruby-version: ${{ matrix.ruby }}

View File

@ -1,23 +0,0 @@
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

@ -1,7 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2020 kojix2 Copyright (c) 2020 kojix2
Copyright (c) 2025 Red Data Tools
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,7 +1,7 @@
<div align="center"> <div align="center">
<img src="logo.svg"> <img src="logo.svg">
<hr> <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> <img alt="Build Status" src="https://github.com/red-data-tools/YouPlot/workflows/test/badge.svg">
<a href="https://rubygems.org/gems/youplot/"><img alt="Gem Version" src="https://badge.fury.io/rb/youplot.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://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="https://rubydoc.info/gems/youplot/"><img alt="Docs Stable" src="https://img.shields.io/badge/docs-stable-blue.svg"></a>
@ -15,24 +15,6 @@
## Installation ## Installation
``` ```
brew install youplot
```
```
gem install youplot
```
```
nix shell nixpkgs#youplot
```
```
guix install youplot
```
```
conda install -c conda-forge ruby
conda install -c conda-forge compilers
gem install youplot gem install youplot
``` ```
@ -55,20 +37,13 @@ curl -sL https://git.io/ISLANDScsv \
<img alt="barplot" src="https://user-images.githubusercontent.com/5798442/101999903-d36a2d00-3d24-11eb-9361-b89116f44122.png"> <img alt="barplot" src="https://user-images.githubusercontent.com/5798442/101999903-d36a2d00-3d24-11eb-9361-b89116f44122.png">
</p> </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 ### histogram
```sh ```sh
echo -e "from numpy import random;" \ echo -e "from numpy import random;" \
"n = random.randn(10000);" \ "n = random.randn(10000);" \
"print('\\\n'.join(str(i) for i in n))" \ "print('\\\n'.join(str(i) for i in n))" \
| python3 \ | python \
| uplot hist --nbins 20 | uplot hist --nbins 20
``` ```
@ -88,14 +63,6 @@ curl -sL https://git.io/AirPassengers \
<img alt="lineplot" src="https://user-images.githubusercontent.com/5798442/101999825-24c5ec80-3d24-11eb-99f4-c642e8d221bc.png"> <img alt="lineplot" src="https://user-images.githubusercontent.com/5798442/101999825-24c5ec80-3d24-11eb-99f4-c642e8d221bc.png">
</p> </p>
```sh
# 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
```
### scatter ### scatter
```sh ```sh
@ -108,12 +75,6 @@ curl -sL https://git.io/IRIStsv \
<img alt="scatter" src="https://user-images.githubusercontent.com/5798442/101999827-27284680-3d24-11eb-9903-551857eaa69c.png"> <img alt="scatter" src="https://user-images.githubusercontent.com/5798442/101999827-27284680-3d24-11eb-9903-551857eaa69c.png">
</p> </p>
```sh
# For offline users
cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot scatter -H -d, -t IRIS
```
### density ### density
```sh ```sh
@ -126,11 +87,6 @@ curl -sL https://git.io/IRIStsv \
<img alt="density" src="https://user-images.githubusercontent.com/5798442/101999828-2abbcd80-3d24-11eb-902c-2f44266fa6ae.png"> <img alt="density" src="https://user-images.githubusercontent.com/5798442/101999828-2abbcd80-3d24-11eb-902c-2f44266fa6ae.png">
</p> </p>
```sh
# For offline users
cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot density -H -d, -t IRIS
```
### boxplot ### boxplot
```sh ```sh
@ -143,21 +99,8 @@ curl -sL https://git.io/IRIStsv \
<img alt="boxplot" src="https://user-images.githubusercontent.com/5798442/101999830-2e4f5480-3d24-11eb-8891-728c18bf5b35.png"> <img alt="boxplot" src="https://user-images.githubusercontent.com/5798442/101999830-2e4f5480-3d24-11eb-8891-728c18bf5b35.png">
</p> </p>
```sh
# For offline users
cat test/fixtures/iris.csv | cut -f1-4 -d, | uplot boxplot -H -d, -t IRIS
```
### count ### count
Count processes by user ID.
```sh
ps aux | awk '{print $1}' | uplot count
```
Count the number of chromosomes where genes are located.
```sh ```sh
cat gencode.v35.annotation.gff3 \ cat gencode.v35.annotation.gff3 \
| grep -v '#' | grep 'gene' | cut -f1 \ | grep -v '#' | grep 'gene' | cut -f1 \
@ -168,6 +111,7 @@ cat gencode.v35.annotation.gff3 \
<img alt="count" src="https://user-images.githubusercontent.com/5798442/101999832-30b1ae80-3d24-11eb-96fe-e5000bed1f5c.png"> <img alt="count" src="https://user-images.githubusercontent.com/5798442/101999832-30b1ae80-3d24-11eb-96fe-e5000bed1f5c.png">
</p> </p>
In this example, YouPlot counts the number of chromosomes where genes are located.
* [GENCODE - Human Release](https://www.gencodegenes.org/human/) * [GENCODE - Human Release](https://www.gencodegenes.org/human/)
Note: `count` is not very fast because it runs in a Ruby script. Note: `count` is not very fast because it runs in a Ruby script.
@ -213,7 +157,7 @@ The following sub-commands are available.
* `-o` * `-o`
* By default, the plot is output to **standard error output**. * 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 | `. * If you want to output to standard input, Use hyphen ` -o -` or no argument `uplot s -o | `.
### Output the input data ### Output the input data
@ -267,14 +211,6 @@ The following sub-commands are available.
* Not yet supported. * 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.
```
uplot --config
```
## Tools that are useful to use with YouPlot ## Tools that are useful to use with YouPlot
* [csvtk](https://github.com/shenwei356/csvtk) * [csvtk](https://github.com/shenwei356/csvtk)
@ -305,13 +241,9 @@ bundle exec rake install # Installation from source code
bundle exec exe/uplot # Run youplot (Try out the edited 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 ### Acknowledgements
* [sampo grafiikka](https://lepo.sampo-grafiikka.com/) - Project logo creation * [sampo grafiikka](https://jypg.net/sampo_grafiikka) - Project logo creation
* [yutaas](https://github.com/yutaas) - English proofreading * [yutaas](https://github.com/yutaas) - English proofreading
## License ## License

View File

@ -63,15 +63,9 @@ module YouPlot
# normal mode # normal mode
else else
# Sometimes the input file does not end with a newline code. # Sometimes the input file does not end with a newline code.
begin while (input = Kernel.gets(nil))
begin
input = Kernel.gets(nil)
rescue Errno::ENOENT => e
warn e.message
next
end
main(input) main(input)
end until input end
end end
end end
@ -141,12 +135,7 @@ module YouPlot
rescue CSV::MalformedCSVError => e rescue CSV::MalformedCSVError => e
warn 'Failed to parse the text. ' warn 'Failed to parse the text. '
warn 'Please try to set the correct character encoding with --encoding option.' warn 'Please try to set the correct character encoding with --encoding option.'
warn e.backtrace.grep(/youplot/).first raise e
exit 1
rescue ArgumentError => e
warn 'Failed to parse the text. '
warn e.backtrace.grep(/youplot/).first
exit 1
end end
data data
@ -160,9 +149,9 @@ module YouPlot
@backend.barplot(data, params, count: true, reverse: options[:reverse]) @backend.barplot(data, params, count: true, reverse: options[:reverse])
when :hist, :histogram when :hist, :histogram
@backend.histogram(data, params) @backend.histogram(data, params)
when :line, :lineplot, :l when :line, :lineplot
@backend.line(data, params, options[:fmt]) @backend.line(data, params, options[:fmt])
when :lines, :lineplots, :ls when :lines, :lineplots
@backend.lines(data, params, options[:fmt]) @backend.lines(data, params, options[:fmt])
when :scatter, :s when :scatter, :s
@backend.scatter(data, params, options[:fmt]) @backend.scatter(data, params, options[:fmt])

View File

@ -9,8 +9,7 @@ module YouPlot
class Error < StandardError; end class Error < StandardError; end
attr_reader :command, :options, :params, attr_reader :command, :options, :params,
:main_parser, :sub_parser, :main_parser, :sub_parser
:config_file, :config
def initialize def initialize
@command = nil @command = nil
@ -31,61 +30,6 @@ module YouPlot
@params = Parameters.new @params = Parameters.new
end 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 def create_base_parser
OptionParser.new do |parser| OptionParser.new do |parser|
parser.program_name = 'YouPlot' parser.program_name = 'YouPlot'
@ -160,9 +104,6 @@ module YouPlot
puts parser.help puts parser.help
exit if YouPlot.run_as_executable? exit if YouPlot.run_as_executable?
end end
parser.on('--config FILE', 'specify a config file') do |v|
@config_file = v
end
parser.on('--debug', TrueClass, 'print preprocessed data') do |v| parser.on('--debug', TrueClass, 'print preprocessed data') do |v|
options[:debug] = v options[:debug] = v
end end
@ -189,12 +130,11 @@ module YouPlot
scatter s draw a scatter plot scatter s draw a scatter plot
density d draw a density plot density d draw a density plot
boxplot box draw a horizontal boxplot boxplot box draw a horizontal boxplot
count c draw a barplot based on the number of count c draw a baplot based on the number of
occurrences (slow) occurrences (slow)
colors color show the list of available colors colors color show the list of available colors
General options: General options:
--config print config file info
--help print command specific help menu --help print command specific help menu
--version print the version of YouPlot --version print the version of YouPlot
MSG MSG
@ -202,36 +142,10 @@ module YouPlot
# Help for the main parser is simple. # Help for the main parser is simple.
# Simply show the banner above. # Simply show the banner above.
main_parser.on('--help', 'print sub-command help menu') do main_parser.on('--help', 'print sub-command help menu') do
show_main_help puts main_parser.banner
puts
exit if YouPlot.run_as_executable?
end 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 end
def sub_parser_add_symbol def sub_parser_add_symbol
@ -301,13 +215,10 @@ module YouPlot
case command case command
# If you type only `uplot` in the terminal. # If you type only `uplot` in the terminal.
# Output help to standard error output.
when nil when nil
show_main_help($stderr) warn main_parser.banner
warn "\n"
# Output help to standard output. exit 1 if YouPlot.run_as_executable?
when :help
show_main_help
when :barplot, :bar when :barplot, :bar
sub_parser_add_symbol sub_parser_add_symbol
@ -330,14 +241,14 @@ module YouPlot
params.nbins = v params.nbins = v
end end
when :lineplot, :line, :l when :lineplot, :line
sub_parser_add_canvas sub_parser_add_canvas
sub_parser_add_grid sub_parser_add_grid
sub_parser_add_fmt_yx sub_parser_add_fmt_yx
sub_parser_add_ylim sub_parser_add_ylim
sub_parser_add_xlim sub_parser_add_xlim
when :lineplots, :lines, :ls when :lineplots, :lines
sub_parser_add_canvas sub_parser_add_canvas
sub_parser_add_grid sub_parser_add_grid
sub_parser_add_fmt_xyxy sub_parser_add_fmt_xyxy
@ -366,19 +277,14 @@ module YouPlot
options[:color_names] = v options[:color_names] = v
end 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 else
error_message = "YouPlot: unrecognized command '#{command}'" error_message = "uplot: unrecognized command '#{command}'"
raise Error, error_message unless YouPlot.run_as_executable? if YouPlot.run_as_executable?
warn error_message
warn error_message exit 1
exit 1 else
raise Error, error_message
end
end end
end end
@ -386,7 +292,7 @@ module YouPlot
begin begin
create_main_parser.order!(argv) create_main_parser.order!(argv)
rescue OptionParser::ParseError => e rescue OptionParser::ParseError => e
warn "YouPlot: #{e.message}" warn "uplot: #{e.message}"
exit 1 if YouPlot.run_as_executable? exit 1 if YouPlot.run_as_executable?
end end
@ -395,14 +301,7 @@ module YouPlot
begin begin
create_sub_parser&.parse!(argv) create_sub_parser&.parse!(argv)
rescue OptionParser::ParseError => e rescue OptionParser::ParseError => e
warn "YouPlot: #{e.message}" warn "uplot: #{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? exit 1 if YouPlot.run_as_executable?
end end
end end

View File

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

View File

@ -69,12 +69,6 @@ class YouPlotIRISTest < Test::Unit::TestCase
assert_equal fixture('iris-lineplot.txt'), @stderr_file.read assert_equal fixture('iris-lineplot.txt'), @stderr_file.read
end 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 test :lineplots do
YouPlot::Command.new(['lineplots', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run YouPlot::Command.new(['lineplots', '-H', '-d,', '-t', 'IRIS-LINEPLOTS']).run
assert_equal fixture('iris-lineplots.txt'), @stderr_file.read assert_equal fixture('iris-lineplots.txt'), @stderr_file.read
@ -85,12 +79,6 @@ class YouPlotIRISTest < Test::Unit::TestCase
assert_equal fixture('iris-lineplots.txt'), @stderr_file.read assert_equal fixture('iris-lineplots.txt'), @stderr_file.read
end 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 test :scatter do
YouPlot::Command.new(['scatter', '-H', '-d,', '-t', 'IRIS-SCATTER']).run YouPlot::Command.new(['scatter', '-H', '-d,', '-t', 'IRIS-SCATTER']).run
assert_equal fixture('iris-scatter.txt'), @stderr_file.read assert_equal fixture('iris-scatter.txt'), @stderr_file.read

View File

@ -12,13 +12,12 @@ Gem::Specification.new do |spec|
spec.description = '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.homepage = 'https://github.com/red-data-tools/YouPlot'
spec.license = 'MIT' spec.license = 'MIT'
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0') spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
spec.files = Dir['*.{md,txt}', '{lib,exe}/**/*'] spec.files = Dir['*.{md,txt}', '{lib,exe}/**/*']
spec.bindir = 'exe' spec.bindir = 'exe'
spec.executables = %w[uplot youplot] spec.executables = %w[uplot youplot]
spec.require_paths = ['lib'] spec.require_paths = ['lib']
spec.add_dependency 'csv'
spec.add_dependency 'unicode_plot', '>= 0.0.5' spec.add_dependency 'unicode_plot', '>= 0.0.5'
end end