youplot 0.3.4 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39029ea73cd1233a1ad890343381986b5fcf46e1e7619708cd0329269d07135c
4
- data.tar.gz: '08662eaab8c28351e57727c69f2f5479e1950d3cbbad7d65ab61ec8994830fec'
3
+ metadata.gz: 04d898a5d15b1a38a92bf3823b6c1a971d17acf6000740867c09f35fa78a2a06
4
+ data.tar.gz: 9c5353687b33c75e953458fc824b1fa7386f980fbd9b11994f94bb8f06e6a387
5
5
  SHA512:
6
- metadata.gz: 7f24fc609bf6501d9b9f6a6452db84d015cfbea7fe6c3a86f4d69ab31043c5a99d9907fe8dbf34f2672589fbfa99e51cde6cfab578c1ef570552e649a7ebfb10
7
- data.tar.gz: 6fb46f5492480a385dec175d022e693442c43cdead3b5bd948dfdc0030a81d661ea5363cb386c9c9f7da5e25329cdc11c286d78985cc9383f7032a3a56a8435a
6
+ metadata.gz: 5677d91bdd78e7de332557434fe377d316e302abb7476ee99fef0fab3dee03a40c702c10d7e1b70cc1cb22e8c5049236408849cc3f208c8372c70ce2dcb251d6
7
+ data.tar.gz: a5948c77d03ec831357c9774e8ef3346b7684944b606b5598620e4723fd233160af6a32377436d1ef4271655cbd3078572cb5f88c14de4ddd63043778dc99c00
data/README.md CHANGED
@@ -1,16 +1,19 @@
1
- <p align="center">
2
- <img src="https://user-images.githubusercontent.com/5798442/103439598-9e952a00-4c81-11eb-881f-67c593bb7861.png" width="75%" height="75%" />
3
- </p>
4
-
5
- ![Build Status](https://github.com/kojix2/youplot/workflows/test/badge.svg)
6
- [![Gem Version](https://badge.fury.io/rb/youplot.svg)](https://badge.fury.io/rb/youplot)
7
- [![Docs Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://rubydoc.info/gems/youplot)
8
- [![The MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
9
- [![DOI](https://zenodo.org/badge/283230219.svg)](https://zenodo.org/badge/latestdoi/283230219)
10
-
11
- YouPlot is a command line tool for Unicode Plotting working with data from standard stream.
12
-
13
- :bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
1
+ <div align="center">
2
+ <img src="logo.svg" width="66%" height="66%" />
3
+
4
+ <hr>
5
+
6
+ ![Build Status](https://github.com/red-data-tools/YouPlot/workflows/test/badge.svg)
7
+ [![Gem Version](https://badge.fury.io/rb/youplot.svg)](https://badge.fury.io/rb/youplot)
8
+ [![Docs Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://rubydoc.info/gems/youplot)
9
+ [![The MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
10
+ [![DOI](https://zenodo.org/badge/283230219.svg)](https://zenodo.org/badge/latestdoi/283230219)
11
+
12
+ YouPlot is a command line tool that draws plots in a terminal.
13
+
14
+ :bar_chart: Powered by [UnicodePlot](https://github.com/red-data-tools/unicode_plot.rb)
15
+
16
+ </div>
14
17
 
15
18
  ## Installation
16
19
 
@@ -106,8 +109,8 @@ In this example, YouPlot counts the number of chromosomes where the gene is loca
106
109
 
107
110
  ```sh
108
111
  cat gencode.v35.annotation.gff3 \
109
- | grep -v '#' | grep 'gene' | cut -f1 | \
110
- uplot count -t "The number of human gene annotations per chromosome" -c blue
112
+ | grep -v '#' | grep 'gene' | cut -f1 \
113
+ | uplot count -t "The number of human gene annotations per chromosome" -c blue
111
114
  ```
112
115
 
113
116
  <p align="center">
@@ -119,7 +122,7 @@ This is fine in most cases, as long as the data size is small. If you want to vi
119
122
 
120
123
  ```sh
121
124
  cat gencode.v35.annotation.gff3 | grep -v '#' | grep 'gene' | cut -f1 \
122
- |sort | uniq -c | sort -nrk2 | awk '{print $2,$1}' \
125
+ | sort | uniq -c | sort -nrk2 | awk '{print $2,$1}' \
123
126
  | uplot bar -d ' ' -t "The number of human gene annotations per chromosome" -c blue
124
127
  ```
125
128
 
@@ -130,15 +133,15 @@ cat gencode.v35.annotation.gff3 | grep -v '#' | grep 'gene' | cut -f1 \
130
133
  Wouldn't it be a pain to have to run R, Python, Julia, gnuplot or whatever REPL just to check your data?
131
134
  YouPlot is a command line tool for this purpose. With YouPlot, you can continue working without leaving your terminal and shell.
132
135
 
133
- ### how to use YouPlot?
136
+ ### How to use YouPlot?
134
137
 
135
138
  `uplot` is the shortened form of `youplot`. You can use either.
136
139
 
137
- | | |
138
- |-----------------------------------|------------------------------------------------|
139
- | Reads data from standard input | `cat data.tsv \| uplot <command> [options]` |
140
- | Reads data from files | `uplot <command> [options] data.tsv ...` |
141
- | Outputs data from stdin to stdout | `pipeline1 \| uplot <command> -O \| pipeline2` |
140
+ | Command | Description |
141
+ |------------------------------------------------|-----------------------------------|
142
+ | `cat data.tsv \| uplot <command> [options]` | Take input from stdin |
143
+ | `uplot <command> [options] data.tsv ...` | Take input from files |
144
+ | `pipeline1 \| uplot <command> -O \| pipeline2` | Outputs data from stdin to stdout |
142
145
 
143
146
  ### Where to output the plot?
144
147
 
@@ -148,7 +151,8 @@ The output file or stream for the plot can be specified with the `-o` option.
148
151
  ### Where to output the input data?
149
152
 
150
153
  By default, the input data is not shown anywhere.
151
- The `-O` option, with no arguments, outputs the input data directly to the standard output. This is useful when passing data to a subsequent pipeline.
154
+ The `-O` option, with no arguments, outputs the input data directly to the standard output.
155
+ This is useful when passing data to a subsequent pipeline.
152
156
 
153
157
  ### What types of plots are available?
154
158
 
@@ -176,11 +180,21 @@ If your input data contains a header line, you need to specify the `-H` option.
176
180
 
177
181
  ### How to specify the delimiter?
178
182
 
179
- Use the `-d` option. To specify a blank space, you can use `uplot bar -d ' ' data.txt`. You do not need to use `-d` option for tab-delimited text since the default value is tab.
183
+ Use the `-d` option. To specify a blank space, you can use `uplot bar -d ' ' data.txt`.
184
+ You do not need to use `-d` option for tab-delimited text since the default value is tab.
180
185
 
181
186
  ### Is there a way to specify a column as the x-axis or y-axis?
182
187
 
183
- Not yet. In principle, YouPlot treats the first column as the X axis and the second column as the Y axis. When working with multiple series, the first row is the X axis, the second row is series 1, the third row is series 2, 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. The `--fmt xyy`, `--fmt xyxy` and `--fmt yx` options give you a few more choices. See `youplot <command> --help` for more details. YouPlot has limited functionalities, but you can use shell scripts such as `awk '{print $2, $1}'` to swap lines.
188
+ Not yet.
189
+ YouPlot treats the first column as the X axis and the second column as the Y axis.
190
+ 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.
191
+ 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.
192
+
193
+ * `--fmt xyy` `--fmt xyxy` `--fmt yx` options give you a few more choices.
194
+ See `youplot <command> --help` for more details.
195
+
196
+ * Use `awk '{print $2, $1}'` to swap lines.
197
+ * Use `paste` to concatenate series.
184
198
 
185
199
  ### How to plot real-time data?
186
200
 
@@ -216,18 +230,21 @@ uplot colors
216
230
 
217
231
  ## Contributing
218
232
 
219
- * [Report bugs](https://github.com/kojix2/youplot/issues)
220
- * Fix bugs and [submit pull requests](https://github.com/kojix2/youplot/pulls)
233
+ YouPlot is a library under development, so even small improvements like typofix are welcome!
234
+ Please feel free to send us your pull requests.
235
+
236
+ * [Report bugs](https://github.com/red-data-tools/YouPlot/issues)
237
+ * Fix bugs and [submit pull requests](https://github.com/red-data-tools/YouPlot/pulls)
221
238
  * Write, clarify, or fix documentation
222
239
  * English corrections by native speakers are welcome.
223
240
  * Suggest or add new features
224
-
241
+ * Make a donation
225
242
 
226
243
  ### Development
227
244
 
228
245
  ```sh
229
- git clone https://github.com/your_name/GR.rb # Clone the Git repo
230
- cd GR.rb
246
+ # fork the main repository by clicking the Fork button.
247
+ git clone https://github.com/your_name/YouPlot
231
248
  bundle install # Install the gem dependencies
232
249
  bundle exec rake test # Run the test
233
250
  bundle exec rake install # Installation from source code
@@ -235,7 +252,6 @@ bundle exec rake install # Installation from source code
235
252
 
236
253
  ### Acknowledgements
237
254
 
238
- * [Red Data Tools](https://github.com/red-data-tools) - Technical support
239
255
  * [sampo grafiikka](https://jypg.net/sampo_grafiikka) - Project logo creation
240
256
  * [yutaas](https://github.com/yutaas) - English proofreading
241
257
 
@@ -6,18 +6,30 @@ module YouPlot
6
6
  module Processing
7
7
  module_function
8
8
 
9
- def count_values(arr, tally: true)
9
+ def count_values(arr, tally: true, reverse: false)
10
10
  # tally was added in Ruby 2.7
11
- if tally && Enumerable.method_defined?(:tally)
12
- arr.tally
13
- else
14
- # https://github.com/marcandre/backports
15
- arr.each_with_object(Hash.new(0)) { |item, res| res[item] += 1 }
16
- .tap { |h| h.default = nil }
11
+ result = \
12
+ if tally && Enumerable.method_defined?(:tally)
13
+ arr.tally
14
+ else
15
+ # value_counts Enumerable::Statistics
16
+ arr.value_counts(dropna: false)
17
+ end
18
+
19
+ # sorting
20
+ result = result.sort do |a, b|
21
+ # compare values
22
+ r = b[1] <=> a[1]
23
+ # If the values are the same, compare by name
24
+ r = a[0] <=> b[0] if r.zero?
25
+ r
17
26
  end
18
- .sort { |a, b| a[1] <=> b[1] }
19
- .reverse
20
- .transpose
27
+
28
+ # --reverse option
29
+ result.reverse! if reverse
30
+
31
+ # prepare for barplot
32
+ result.transpose
21
33
  end
22
34
  end
23
35
  end
@@ -1,22 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # UnicodePlot - Plot your data by Unicode characters
4
+ # https://github.com/red-data-tools/unicode_plot.rb
5
+
3
6
  require_relative 'processing'
4
7
  require 'unicode_plot'
5
8
 
6
9
  module YouPlot
7
10
  # plotting functions.
8
11
  module Backends
9
- module UnicodePlotBackend
12
+ module UnicodePlot
10
13
  class Error < StandardError; end
11
14
 
12
15
  module_function
13
16
 
14
- def barplot(data, params, fmt = nil, count: false)
17
+ def barplot(data, params, fmt = nil, count: false, reverse: false)
15
18
  headers = data.headers
16
19
  series = data.series
17
20
  # `uplot count`
18
21
  if count
19
- series = Processing.count_values(series[0])
22
+ series = Processing.count_values(series[0], reverse: reverse)
20
23
  params.title = headers[0] if headers
21
24
  end
22
25
  if series.size == 1
@@ -39,19 +42,7 @@ module YouPlot
39
42
  labels = series[x_col]
40
43
  values = series[y_col].map(&:to_f)
41
44
  end
42
- begin
43
- UnicodePlot.barplot(labels, values, **params.to_hc)
44
- # UnicodePlot error:
45
- # All values have to be positive. Negative bars are not supported.
46
- rescue ArgumentError => e
47
- if YouPlot.run_as_executable?
48
- warn e.backtrace[0]
49
- warn "\e[35m#{e}\e[0m"
50
- exit 1
51
- else
52
- raise e
53
- end
54
- end
45
+ ::UnicodePlot.barplot(labels, values, **params.to_hc)
55
46
  end
56
47
 
57
48
  def histogram(data, params)
@@ -59,7 +50,7 @@ module YouPlot
59
50
  series = data.series
60
51
  params.title ||= data.headers[0] if headers
61
52
  values = series[0].map(&:to_f)
62
- UnicodePlot.histogram(values, **params.to_hc)
53
+ ::UnicodePlot.histogram(values, **params.to_hc)
63
54
  end
64
55
 
65
56
  def line(data, params, fmt = nil)
@@ -69,7 +60,7 @@ module YouPlot
69
60
  # If there is only one series, it is assumed to be sequential data.
70
61
  params.ylabel ||= headers[0] if headers
71
62
  y = series[0].map(&:to_f)
72
- UnicodePlot.lineplot(y, **params.to_hc)
63
+ ::UnicodePlot.lineplot(y, **params.to_hc)
73
64
  else
74
65
  # If there are 2 or more series...
75
66
  if fmt == 'yx'
@@ -87,7 +78,7 @@ module YouPlot
87
78
  end
88
79
  x = series[x_col].map(&:to_f)
89
80
  y = series[y_col].map(&:to_f)
90
- UnicodePlot.lineplot(x, y, **params.to_hc)
81
+ ::UnicodePlot.lineplot(x, y, **params.to_hc)
91
82
  end
92
83
  end
93
84
 
@@ -106,9 +97,9 @@ module YouPlot
106
97
  end
107
98
  params.xlim ||= series[0].flatten.minmax # why need?
108
99
  params.ylim ||= series[1..-1].flatten.minmax # why need?
109
- plot = UnicodePlot.public_send(method1, series[0], series[1], **params.to_hc)
100
+ plot = ::UnicodePlot.public_send(method1, series[0], series[1], **params.to_hc)
110
101
  2.upto(series.size - 1) do |i|
111
- UnicodePlot.public_send(method2, plot, series[0], series[i], name: headers&.[](i))
102
+ ::UnicodePlot.public_send(method2, plot, series[0], series[i], name: headers&.[](i))
112
103
  end
113
104
  plot
114
105
  end
@@ -124,9 +115,9 @@ module YouPlot
124
115
  params.xlim ||= series2.map(&:first).flatten.minmax # why need?
125
116
  params.ylim ||= series2.map(&:last).flatten.minmax # why need?
126
117
  x1, y1 = series2.shift
127
- plot = UnicodePlot.public_send(method1, x1, y1, **params.to_hc)
118
+ plot = ::UnicodePlot.public_send(method1, x1, y1, **params.to_hc)
128
119
  series2.each_with_index do |(xi, yi), i|
129
- UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
120
+ ::UnicodePlot.public_send(method2, plot, xi, yi, name: headers&.[]((i + 1) * 2))
130
121
  end
131
122
  plot
132
123
  end
@@ -164,13 +155,13 @@ module YouPlot
164
155
  series = data.series
165
156
  headers ||= (1..series.size).map(&:to_s)
166
157
  series.map! { |s| s.map(&:to_f) }
167
- UnicodePlot.boxplot(headers, series, **params.to_hc)
158
+ ::UnicodePlot.boxplot(headers, series, **params.to_hc)
168
159
  end
169
160
 
170
161
  def colors(color_names = false)
171
162
  # FIXME
172
163
  s = String.new
173
- UnicodePlot::StyledPrinter::TEXT_COLORS.each do |k, v|
164
+ ::UnicodePlot::StyledPrinter::TEXT_COLORS.each do |k, v|
174
165
  s << v
175
166
  s << k.to_s
176
167
  unless color_names
@@ -190,18 +181,24 @@ module YouPlot
190
181
  def check_series_size(data, fmt)
191
182
  series = data.series
192
183
  if series.size == 1
193
- warn 'youplot: There is only one series of input data. Please check the delimiter.'
194
- warn ''
195
- warn " Headers: \e[35m#{data.headers.inspect}\e[0m"
196
- warn " The first item is: \e[35m\"#{series[0][0]}\"\e[0m"
197
- warn " The last item is : \e[35m\"#{series[0][-1]}\"\e[0m"
184
+ warn <<~EOS
185
+ youplot: There is only one series of input data. Please check the delimiter.
186
+
187
+ Headers: \e[35m#{data.headers.inspect}\e[0m
188
+ The first item is: \e[35m\"#{series[0][0]}\"\e[0m
189
+ The last item is : \e[35m\"#{series[0][-1]}\"\e[0m
190
+ EOS
191
+ # NOTE: Error messages cannot be colored.
198
192
  YouPlot.run_as_executable ? exit(1) : raise(Error)
199
193
  end
200
194
  if fmt == 'xyxy' && series.size.odd?
201
- warn 'YouPlot: In the xyxy format, the number of series must be even.'
202
- warn ''
203
- warn " Number of series: \e[35m#{series.size}\e[0m"
204
- warn " Headers: \e[35m#{data.headers.inspect}\e[0m"
195
+ warn <<~EOS
196
+ YouPlot: In the xyxy format, the number of series must be even.
197
+
198
+ Number of series: \e[35m#{series.size}\e[0m
199
+ Headers: \e[35m#{data.headers.inspect}\e[0m
200
+ EOS
201
+ # NOTE: Error messages cannot be colored.
205
202
  YouPlot.run_as_executable ? exit(1) : raise(Error)
206
203
  end
207
204
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'dsv'
4
- require_relative 'command/parser'
4
+ require_relative 'parser'
5
5
 
6
6
  # FIXME
7
- require_relative 'backends/unicode_plot_backend'
7
+ require_relative 'backends/unicode_plot'
8
8
 
9
9
  module YouPlot
10
10
  Data = Struct.new(:headers, :series)
@@ -19,7 +19,7 @@ module YouPlot
19
19
  @command = nil
20
20
  @params = nil
21
21
  @options = nil
22
- @backend = YouPlot::Backends::UnicodePlotBackend
22
+ @backend = YouPlot::Backends::UnicodePlot
23
23
  end
24
24
 
25
25
  def run_as_executable
@@ -33,21 +33,34 @@ module YouPlot
33
33
  @options ||= parser.options
34
34
  @params ||= parser.params
35
35
 
36
+ # color command
36
37
  if %i[colors color colours colour].include? @command
37
38
  plot = create_plot
38
39
  output_plot(plot)
39
- elsif options[:progressive]
40
+ return
41
+ end
42
+
43
+ # progressive mode
44
+ if options[:progressive]
40
45
  stop = false
41
46
  Signal.trap(:INT) { stop = true }
42
- options[:output].print "\e[?25l" # make cursor invisible
47
+
48
+ # make cursor invisible
49
+ options[:output].print "\e[?25l"
50
+
51
+ # mainloop
43
52
  while (input = Kernel.gets)
44
53
  n = main_progressive(input)
45
54
  break if stop
46
55
 
47
56
  options[:output].print "\e[#{n}F"
48
57
  end
58
+
49
59
  options[:output].print "\e[0J"
50
- options[:output].print "\e[?25h" # make cursor visible
60
+ # make cursor visible
61
+ options[:output].print "\e[?25h"
62
+
63
+ # normal mode
51
64
  else
52
65
  # Sometimes the input file does not end with a newline code.
53
66
  while (input = Kernel.gets(nil))
@@ -59,13 +72,32 @@ module YouPlot
59
72
  private
60
73
 
61
74
  def main(input)
75
+ # Outputs input data to a file or stdout.
62
76
  output_data(input)
63
77
 
64
- @data = read_dsv(input)
78
+ @data = parse_dsv(input)
65
79
 
80
+ # Debug mode, show parsed results
66
81
  pp @data if options[:debug]
67
82
 
68
- plot = create_plot
83
+ # When run as a program instead of a library
84
+ if YouPlot.run_as_executable?
85
+ begin
86
+ plot = create_plot
87
+ rescue ArgumentError => e
88
+ # Show only one line of error.
89
+ warn e.backtrace[0]
90
+ # Show error message in purple
91
+ warn "\e[35m#{e}\e[0m"
92
+ # Explicitly terminated with exit code: 1
93
+ exit 1
94
+ end
95
+
96
+ # When running YouPlot as a library (e.g. for testing)
97
+ else
98
+ plot = create_plot
99
+ end
100
+
69
101
  output_plot(plot)
70
102
  end
71
103
 
@@ -85,15 +117,28 @@ module YouPlot
85
117
  @raw_data << input
86
118
 
87
119
  # FIXME
88
- @data = read_dsv(@raw_data)
120
+ @data = parse_dsv(@raw_data)
89
121
 
90
122
  plot = create_plot
91
123
  output_plot_progressive(plot)
92
124
  end
93
125
 
94
- def read_dsv(input)
95
- input = input.dup.force_encoding(options[:encoding]).encode('utf-8') if options[:encoding]
96
- DSV.parse(input, options[:delimiter], options[:headers], options[:transpose])
126
+ def parse_dsv(input)
127
+ # If encoding is specified, convert to UTF-8
128
+ if options[:encoding]
129
+ input.force_encoding(options[:encoding])
130
+ .encode!('utf-8')
131
+ end
132
+
133
+ begin
134
+ data = DSV.parse(input, options[:delimiter], options[:headers], options[:transpose])
135
+ rescue CSV::MalformedCSVError => e
136
+ warn 'Failed to parse the text. '
137
+ warn 'Please try to set the correct character encoding with --encoding option.'
138
+ raise e
139
+ end
140
+
141
+ data
97
142
  end
98
143
 
99
144
  def create_plot
@@ -101,7 +146,7 @@ module YouPlot
101
146
  when :bar, :barplot
102
147
  @backend.barplot(data, params, options[:fmt])
103
148
  when :count, :c
104
- @backend.barplot(data, params, count: true)
149
+ @backend.barplot(data, params, count: true, reverse: options[:reverse])
105
150
  when :hist, :histogram
106
151
  @backend.histogram(data, params)
107
152
  when :line, :lineplot
@@ -137,9 +182,9 @@ module YouPlot
137
182
 
138
183
  def output_plot(plot)
139
184
  case options[:output]
140
- when IO
185
+ when IO, StringIO
141
186
  plot.render(options[:output])
142
- else
187
+ when String, Tempfile
143
188
  File.open(options[:output], 'w') do |f|
144
189
  plot.render(f)
145
190
  end
@@ -148,7 +193,7 @@ module YouPlot
148
193
 
149
194
  def output_plot_progressive(plot)
150
195
  case options[:output]
151
- when IO
196
+ when IO, StringIO
152
197
  # RefactorMe
153
198
  out = StringIO.new(String.new)
154
199
  def out.tty?
data/lib/youplot/dsv.rb CHANGED
@@ -3,41 +3,49 @@
3
3
  require 'csv'
4
4
 
5
5
  module YouPlot
6
- # Read and interpret Delimiter-separated values format file or stream.
6
+ # Module to handle DSV (Delimiter-separated values) format.
7
+ # Extract header and series.
7
8
  module DSV
8
9
  module_function
9
10
 
10
11
  def parse(input, delimiter, headers, transpose)
11
- arr = parse_as_csv(input, delimiter)
12
+ # Parse as CSV
13
+ arr = CSV.parse(input, col_sep: delimiter)
14
+
15
+ # Remove blank lines
16
+ arr.delete_if do |i|
17
+ i == [] or i.all?(&:nil?)
18
+ end
19
+
20
+ # get header
12
21
  headers = get_headers(arr, headers, transpose)
22
+
23
+ # get series
13
24
  series = get_series(arr, headers, transpose)
14
- if headers.nil?
15
- Data.new(headers, series)
16
- else
17
- if headers.include?(nil)
18
- warn "\e[35mHeaders contains nil in it.\e[0m"
19
- elsif headers.include? ''
20
- warn "\e[35mHeaders contains \"\" in it.\e[0m"
21
- end
22
- h_size = headers.size
23
- s_size = series.size
24
- if h_size == s_size
25
- Data.new(headers, series)
26
- elsif h_size > s_size
27
- warn "\e[35mThe number of headers is greater than the number of series.\e[0m"
28
- exit 1 if YouPlot.run_as_executable?
29
- elsif h_size < s_size
30
- warn "\e[35mThe number of headers is less than the number of series.\e[0m"
31
- exit 1 if YouPlot.run_as_executable?
32
- end
25
+
26
+ # Return if No header
27
+ return Data.new(headers, series) if headers.nil?
28
+
29
+ # Warn if header contains nil
30
+ warn "\e[35mHeaders contains nil in it.\e[0m" if headers.include?(nil)
31
+
32
+ # Warn if header contains ''
33
+ warn "\e[35mHeaders contains \"\" in it.\e[0m" if headers.include? ''
34
+
35
+ # Make sure the number of elements in the header matches the number of series.
36
+ h_size = headers.size
37
+ s_size = series.size
38
+
39
+ if h_size > s_size
40
+ warn "\e[35mThe number of headers is greater than the number of series.\e[0m"
41
+ exit 1 if YouPlot.run_as_executable?
42
+
43
+ elsif h_size < s_size
44
+ warn "\e[35mThe number of headers is less than the number of series.\e[0m"
45
+ exit 1 if YouPlot.run_as_executable?
33
46
  end
34
- end
35
47
 
36
- def parse_as_csv(input, delimiter)
37
- CSV.parse(input, col_sep: delimiter)
38
- .delete_if do |i|
39
- i == [] or i.all? nil
40
- end
48
+ Data.new(headers, series) if h_size == s_size
41
49
  end
42
50
 
43
51
  # Transpose different sized ruby arrays
@@ -47,31 +55,33 @@ module YouPlot
47
55
  end
48
56
 
49
57
  def get_headers(arr, headers, transpose)
50
- if headers
51
- if transpose
52
- arr.map(&:first)
53
- else
54
- arr[0]
55
- end
56
- end
58
+ # header(-)
59
+ return nil unless headers
60
+
61
+ # header(+) trenspose(+)
62
+ return arr.map(&:first) if transpose
63
+
64
+ # header(+) transpose(-)
65
+ arr[0]
57
66
  end
58
67
 
59
68
  def get_series(arr, headers, transpose)
60
- if headers
61
- if arr.size > 1
62
- if transpose
63
- arr.map { |row| row[1..-1] }
64
- else
65
- transpose2(arr[1..-1])
66
- end
67
- else
68
- Array.new(arr[0].size, [])
69
- end
70
- elsif transpose
71
- arr
72
- else
73
- transpose2(arr)
69
+ # header(-)
70
+ unless headers
71
+ return arr if transpose
72
+
73
+ return transpose2(arr)
74
74
  end
75
+
76
+ # header(+) but no element in the series.
77
+ # TODO: should raise error?
78
+ return Array.new(arr[0].size, []) if arr.size == 1
79
+
80
+ # header(+) transpose(+)
81
+ return arr.map { |row| row[1..-1] } if transpose
82
+
83
+ # header(+) transpose(-)
84
+ transpose2(arr[1..-1])
75
85
  end
76
86
  end
77
87
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YouPlot
4
+ # Command line options that are not Plot parameters
5
+ Options = Struct.new(
6
+ :delimiter,
7
+ :transpose,
8
+ :headers,
9
+ :pass,
10
+ :output,
11
+ :fmt,
12
+ :progressive,
13
+ :encoding,
14
+ :reverse, # count
15
+ :color_names, # color
16
+ :debug
17
+ )
18
+ end